⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgplicensenumbernet.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
static const char *kContentLength = "Content-Length: ";
static const char *kWarning = "Warning: ";

// look for HTTP optional header
//    Warning: warn-code SP warn-agent SP warn-text
// and parse it, if it was generated by us. 
static PGPError parseHttpWarningHeader( const PGPByte *header, PGPError *remoteError )  {
	PGPByte *p;

	*remoteError = kPGPError_NoErr;
	
	p = strstr( header, kWarning );
	if( p == NULL )  
		return kPGPError_NoErr;
		
	if( p > header+2 && *(p-1)=='\n' && *(p-2)=='\r' ) {
		p += strlen(kWarning);
		
		// HTTP Warning: warn-code SP warn-agent SP warn-text
		// p now points on warn-code
		
		if( atoi(p) == 99 )  {	// we pass PGPError as this "Miscellaneous warning"
			p = strchr( p, ' ' );
			
			if( p )
				p++;	// p points on warn-agent
			else
				return kPGPError_CorruptData;	// HTTP violation
			
			p = strchr( p, ' ' );	// skip warn-agent
			
			if( !p )
				return kPGPError_CorruptData;	// HTTP violation
			
			{
				PGPByte warn_text[40];
				const static PGPByte pgperror[] = "PGPError=";
				
				p++;	// p points on warn-text, this is quoted PGPError=errcode
				
				if( *p == '"' )  {
					strncpy( warn_text, p+1, sizeof(warn_text) );
					warn_text[sizeof(warn_text)-1] = '\0';
					
					p = strchr( warn_text, '"' );	// check for another quote
					if( p )  
						*p = '\0';
					else
						return kPGPError_CorruptData;	// HTTP violation
					
					p = warn_text;
				}
				
				if( strncmp( p, pgperror, sizeof(pgperror)-1 )==0 )  {
					p += sizeof(pgperror)-1;
					*remoteError = atoi(p);	// set output parameter
				}
			}
		}
	}
		
	return kPGPError_NoErr;
}

/* we assume that the first line in HTTP response is in the buffer
   other fields can be absent
 */
static PGPError parseHttpHeader( PGPByte header[kPGPLANet_ReceiveSize], 
	PGPSize *bodySize, PGPSize *headerSize, PGPUInt32 *statusCode )  
{
	PGPByte *p, *p2;
	PGPUInt32 i;
	int curBodySize = 0;
	int curHeaderSize = 0;
	int curStatusCode = 0;

	*bodySize = 0;
	*headerSize = 0;
	*statusCode = 0;

	/* find where body begins and eliminate it. It may not be present */
	p = strstr( header, "\r\n\r\n" );
	if( p != NULL )  {
		p[2] = '\0';
		curHeaderSize = p-header+4;
	}

	/* check for content lenght */
	p = strstr( header, kContentLength );
	if( p != NULL )  {
		if( p > header+2 && *(p-1)=='\n' && *(p-2)=='\r' ) {
			p += strlen(kContentLength);

			i = atoi(p);

			/* check content length that we could generate */
			if( i > 160*2/8 && i < 4*1024 )  {
				curBodySize = i;
			}
		}
	}

	/* now we are done with sizes - parse first line to get return code */
	p2 = strchr( header, '\r' );	
	if( !p2 )  {	/* we expect to get at least one line */
		return kPGPError_CorruptData;
	}

	// header =?= HTTP-Version SP Status-Code SP Reason-Phrase CRLF 

	if( strncmp( header, "HTTP/", 5 )!=0 )
		return kPGPError_CorruptData;

	p = strchr( header, ' ' );
	if( !p )
		return kPGPError_CorruptData;

	p++;
	i = atoi(p);

	if( i<100 )
		return kPGPError_CorruptData;

	curStatusCode = i;

	p = strchr(p, ' ');
	if( !p )
		return kPGPError_CorruptData;

	p++;
	
	/* p is reason */
	if( strchr(p, '\r') != (char *) p2 )
		return kPGPError_CorruptData;	// this wasn't on the first line

	*bodySize = curBodySize;
	*headerSize = curHeaderSize;
	*statusCode = curStatusCode;

	return kPGPError_NoErr;
}

static void sleepSeconds( PGPUInt32 sec )  {
#if PGP_UNIX || PGP_OSX
	usleep(sec * 1000000);
#elif PGP_WIN32
	Sleep(sec * 1000);
#else
	sleep( sec );
#endif
}

static PGPError roundTrip( PGPSocketRef socket, 
			const PGPByte *host_port, const PGPByte *resource, 
			PGPBoolean last, 
			const PGPByte *inData, 
			PGPByte bufferRead[kPGPLANet_ReceiveSize], 
			PGPUInt32 *httpError, PGPError *remotePgpError ) 
{
	static const char *kPost = "POST ";
	static const char *kHTTPVersion_term = " HTTP/1.1\r\n";
	static const char *kContentType = "Content-type: application/x-www-form-urlencoded\r\n";
	static const char *kConnectionKeepAlive = "Connection: Keep-Alive\r\n";
	static const char *kConnectionClose = "Connection: close\r\n";
	static const char *kHost = "Host: ";

	PGPByte bufferSend[kPGPLANet_SendSize];

#if PGP_MACINTOSH
	#define OS " (Macintosh)"
#elif PGP_WIN32
	#define OS " (Windows)"
#elif PGP_UNIX
	#define OS " (Unix)"
#endif
	
	static const char *	kUserAgent = "User-Agent: PGP" OS "\r\n";
	#undef OS

	PGPInt32 socketResult=0;
	const PGPSize inDataLength = inData != NULL ? strlen( inData ) : 0;

 	bufferSend[0] = '\0';
	bufferRead[0] = '\0';

	if( httpError )
		*httpError = 0;

	if( remotePgpError )
		*remotePgpError = kPGPError_NoErr;

	if( inData!=NULL && inData[0]=='\0' )
		inData = NULL;

	/* send first line */
	strcat( bufferSend, kPost );
	strcat( bufferSend, resource);
	strcat( bufferSend, kHTTPVersion_term);

	strcat( bufferSend, kUserAgent);
	strcat( bufferSend, kContentType);

	/* sending Host field */
	strcat( bufferSend, kHost );
	strcat( bufferSend, host_port );
	strcat( bufferSend, "\r\n" );

	strcat( bufferSend, last ? kConnectionClose : kConnectionKeepAlive );

	/* forth line - content length */
	{
		char s[20];
		strcat(bufferSend, kContentLength );
		sprintf(s, "%u\r\n", (unsigned) inDataLength);
		strcat(bufferSend, s );
	}

	/* insert empty line */
	strcat(bufferSend, "\r\n");

#if PGP_DEBUG_PRINT
	fprintf( stderr,"-----begin sending packet-----\n");
	fprintf( stderr,"%s%s\n", bufferSend, inData==NULL ? (const PGPByte*)" " : inData);
	fprintf( stderr,"-----end sending packet-----\n");
#endif

	PGPSend( socket, bufferSend, strlen(bufferSend), kPGPSendFlagNone );

	/* finally, send data */
	if( inData != NULL )
		PGPSend( socket, inData, inDataLength, kPGPSendFlagNone );

	/* now receive data */
	{
		PGPUInt32 bytesRead		= 0;
		PGPInt32 avail;
		PGPSize headerSize, bodySize; 
		PGPUInt32 httpStatusCode; 
		PGPError err;
		PGPError remote_err;
		PGPInt32 max_wait=5;	/* how long receiver waits before declaring timeout */

		do {
			avail = PGPReceive( socket, bufferRead, kPGPLANet_ReceiveSize, MSG_PEEK );
			if( avail == 0 )  {
				sleepSeconds( 1 );
#if PGP_DEBUG_PRINT
				fprintf( stderr,"\twaited one sec to receive data from the socket...\n");
#endif
			}
		} while(max_wait-- > 0 && avail==0);
		
		if( avail==0 ) { /* timed out */
#if PGP_DEBUG_PRINT
			fprintf( stderr,"timed out: no data in the socket\n");
#endif
			return kPGPError_ServerTimedOut;
		}
		if( avail < 0 )
			return PGPGetLastSocketsError();
		
		err = parseHttpHeader( bufferRead, &bodySize, &headerSize, &httpStatusCode );
		if( IsPGPError(err) )
			return err;

		if( httpError )
			*httpError = httpStatusCode;

		/* check for remote PGPError code returned as a warn-text in Warning:  */
		err = parseHttpWarningHeader( bufferRead, &remote_err );
		if( IsPGPError(err) )
			return err;

		if( remotePgpError )
			*remotePgpError = remote_err;

		if( bodySize && headerSize && httpStatusCode==200 && bodySize + headerSize == avail )  {	/* already read */
			bytesRead = avail;
			PGPReceive( socket, bufferSend, avail, kPGPReceiveFlagNone ); 
				// reuse bufferSend for cleaning the socket
		}
		else  {
			avail = bodySize + headerSize;
			if( avail > kPGPLANet_ReceiveSize  )
				avail = kPGPLANet_ReceiveSize;
			while( bytesRead < avail )
			{
				socketResult = PGPReceive( socket, ( (PGPByte *) bufferRead ) + bytesRead, 
							avail-bytesRead, kPGPReceiveFlagNone );
			
				if( socketResult <= 0 )
					break;
				
				bytesRead += socketResult;
			}
		}

		if( socketResult < 0 )  {
			PGPError err = PGPGetLastSocketsError();
			return err;
		}

		if( headerSize )  {
			bufferRead[headerSize-2] = '\0';
			bufferRead[headerSize-1] = '\0';
			bufferRead[bodySize + headerSize] = '\0';
		}

#if PGP_DEBUG_PRINT
		fprintf( stderr,"-----begin received packet-----\n" );
		fprintf( stderr, "%s\n", bufferRead );
		fprintf( stderr, "-----begin body-----\n" );
		fprintf( stderr, "%s\n", bufferRead+headerSize );
		fprintf( stderr,"-----end received packet-----\n");
#endif	/* PGP_DEBUG_PRINT */

		if( bodySize )
			memmove( bufferRead, bufferRead+headerSize, bodySize+1 );
		else
			bufferRead[0] = '\0';
	}

	return kPGPError_NoErr;
}

/* appends application/x-www-form-urlencoded parameter and value,
   encodes all illegal characters as %XX
   See section 2.2 from RFC 1738
  */
static void addFormUrlEncodedParam( const PGPByte *name, const PGPByte *value, 
										PGPByte *buffer )  
{
	PGPByte v[kPGPLANet_SendSize];
	PGPSize len = strlen( buffer );
	PGPUInt32 w_value_len=0;
	PGPByte *p;
	static const PGPByte illegal[] = "&=+% \t\n\r<>\"#{}|\\^[]~`";
	PGPUInt16 wv[kPGPLANet_SendSize];
	PGPUInt32 i;

	if( name == NULL || value == NULL )
		return;

	/* name expect to be OK */	
	pgpAssert( strchr(name, '=')==NULL );

	pgpUTF8StringToUCS2 (
		value, kPGPUnicodeNullTerminated, wv, sizeof(wv)/sizeof(wv[0]),	&w_value_len);

	if( w_value_len==0 )
		return;	/* ignore the pair */

	p = v;

	for( i=0; i<w_value_len; i++ )  {
		PGPByte utf8[8];
		PGPUInt32 utf8_len=0;
		
		pgpUCS2StringToUTF8( wv+i, 1, utf8, sizeof(utf8), &utf8_len );
		if( utf8_len==0 )
			return;	/* ignore the pair */
		utf8[sizeof(utf8)-1] = '\0';

		if( utf8_len==1 && strchr( illegal, wv[i] )==NULL && wv[i] > 0x1f && wv[i] < 0x80 )
			*(p++) = (PGPByte)wv[i];	/* unchacnged  */
		else  {
			/* encode all bytes for the Unicode character */
			PGPUInt32 j;
			PGPByte e[8];
			for( j=0; j<utf8_len; j++ )  {
				sprintf( e, "%%%02X", utf8[j] );
				strcpy( p, e );
				p += 3;
			}
		}
	}

	*p = '\0';

	if( !len )
		sprintf( buffer, "%s=%s", name, v );
	else  {
		buffer += len;
		sprintf( buffer, "&%s=%s", name, v );
	}
}

/* parse parametes in the form of application/x-www-form-urlencoded */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -