GET_SOCK.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:11k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++
  2. Copyright 1996-1997 Microsoft Corporation
  3. Module Name:
  4.     get_sock.c
  5. Abstract:
  6.     This does a get using raw sockets
  7. History:
  8.     09-Nov-1995     Created
  9.     15-Feb-1996     Added authentication support
  10. --*/
  11. #include <windows.h>
  12. #include <winsock.h>
  13. #include <stdio.h>
  14. #include <stdarg.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <tchar.h>
  18. #include <io.h>
  19. #include <fcntl.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include "httpauth.h"
  23. // globals
  24. #define HD_AUTHENTICATE         "WWW-Authenticate:"
  25. #define HD_LENGTH               "Content-Length:"
  26. #define HD_CONNECTION           "Connection:"
  27. // list of Authentication methods to support
  28. char      achAuth[256];
  29. // Helper functions
  30. void SkipWhite(PSTR *ppS )
  31. {
  32.     PSTR pS = *ppS;
  33.     while ( *pS && isspace(*pS) )
  34.         ++pS;
  35.     *ppS = pS;
  36. }
  37. void SkipNonWhite(PSTR *ppS )
  38. {
  39.     PSTR pS = *ppS;
  40.     while ( *pS && !isspace(*pS) )
  41.         ++pS;
  42.     *ppS = pS;
  43. }
  44. BOOL
  45. HttpGetSocket(
  46.     char * Verb,
  47.     char * Server,
  48.     char * URL,
  49.     BOOL   DisplayHeaders,
  50.     DWORD  ClientDataSize,
  51.     PSTR   pchUserName,
  52.     PSTR   pchPassword,
  53.     PSTR   pszStore,
  54.     PSTR   pszPref
  55.     )
  56. /*++
  57.  Routine Description:
  58.     Issue a command to a HTTP server using authentication
  59.  Arguments:
  60.     Verb                HTTP command : GET / HEAD / ...
  61.     Server              server name
  62.     URL                 URL to send to the server
  63.     DisplayHeaders      TRUE to display headers as received
  64.     ClientDataSize      number of bytes to send in the request
  65.     pchUserName         user name for authentication
  66.     pchPassword         password for authentication
  67.     pszStore            file name where to dump reply from server
  68.  Return Value:
  69.     Returns TRUE is successful; otherwise FALSE is returned.
  70. --*/
  71. {
  72.     char               ReceiveBuffer[8*1024];
  73.     int                Error;
  74.     BYTE               Request[1024];
  75.     int                RequestSize;
  76.     char *             AcceptTypes[2] = {"*/*", NULL};
  77.     SOCKET             Socket = INVALID_SOCKET;
  78.     WSADATA            WsaData;
  79.     struct sockaddr_in Address;
  80.     struct hostent *   HostEntry;
  81.     char               Headers[] = 
  82.                            "HTTP/1.0rn"
  83.                            "User-Agent: AuthClientrn"
  84.                            "Accept: */*rn";
  85.     char               CrLf[] = "rn";
  86.     BYTE               ClientData[64*1024];
  87.     BOOL               fKeepAlive = FALSE;
  88.     int                cRec;
  89.     DWORD              cLen;
  90.     BOOL               fInHeader;
  91.     PSTR               pchAuthData;
  92.     BOOL               fServerKeepAlive = FALSE;
  93.     BOOL               fNeedMoreData;
  94.     BOOL               fNeedAuthenticate;
  95.     PSTR               pH;
  96.     PSTR               pN;
  97.     BOOL               fStatusLine;
  98.     int                Status = -1;
  99.     DWORD              cToRead;
  100.     PSTR               paAuth = achAuth;
  101.     BOOL               fSt = FALSE;
  102.     int                hnd = EOF;
  103.     Error = WSAStartup (0x101, &WsaData);
  104.     if (Error == SOCKET_ERROR) 
  105.     {
  106.         fprintf(stderr, "Error in WSAStartup = %dn", GetLastError());
  107.         return FALSE;
  108.     }
  109.     if ( !InitAuthorizationHeader() )
  110.     {
  111.         fprintf(stderr, "Cannot initialize security modulen" );
  112.         return FALSE;
  113.     }
  114.     memset( achAuth, '', sizeof(achAuth) );
  115.     pchAuthData = NULL;
  116.     fNeedAuthenticate = FALSE;
  117.     //
  118.     // Connect to the server
  119.     //
  120.     if  ( pszStore != NULL )
  121.         if ( (hnd = _open( pszStore, _O_BINARY | _O_CREAT | _O_TRUNC | _O_RDWR, S_IREAD|S_IWRITE )) == EOF )
  122.         {
  123.             fprintf( stderr, "Can't create file %sn", pszStore );
  124.             return FALSE;
  125.         }
  126. again:
  127.     if ( Socket == INVALID_SOCKET )
  128.     {
  129.         Socket = socket(AF_INET, SOCK_STREAM, 0);
  130.         if (Socket == INVALID_SOCKET) 
  131.         {
  132.             fprintf(stderr, "Error creating socket = %dn", GetLastError());
  133.             fSt = FALSE;
  134.             goto ex;
  135.         }
  136.         Address.sin_family = AF_INET;
  137.         Address.sin_port = 0;
  138.         Address.sin_addr.s_addr = INADDR_ANY;
  139.         Error = 
  140.         bind(
  141.             Socket,
  142.             (struct sockaddr *) &Address,
  143.             sizeof(Address));
  144.         if (Error) 
  145.         {
  146.             fprintf(stderr, "Error in bind = %dn", GetLastError());
  147.             fSt = FALSE;
  148.             goto ex;
  149.         }
  150.         Address.sin_family = AF_INET;
  151.         Address.sin_port = htons(80);
  152.         Address.sin_addr.s_addr = inet_addr(Server);
  153.         if (Address.sin_addr.s_addr == -1) 
  154.         {
  155.             //
  156.             // Must be a server name
  157.             //
  158.             HostEntry = gethostbyname(Server);
  159.             if (HostEntry == NULL) 
  160.             {
  161.                 printf("unable to resolve %sn", Server);
  162.                 fSt = FALSE;
  163.                 goto ex;
  164.             } else 
  165.             {
  166.                 Address.sin_addr.s_addr = *((unsigned long *) HostEntry->h_addr);
  167.             }
  168.         }
  169.         Error =
  170.         connect(
  171.             Socket,
  172.             (struct sockaddr *) &Address,
  173.             sizeof(Address));
  174.         if (Error) 
  175.         {
  176.             fprintf(stderr, "Error connecting to %s = %dn", Server, GetLastError());
  177.             fSt = FALSE;
  178.             goto ex;
  179.         }
  180.     }
  181.     //
  182.     // Send the client request
  183.     //
  184.     strcpy(Request, Verb);
  185.     strcat(Request, " ");
  186.     strcat(Request, URL);
  187.     strcat(Request, " ");
  188.     strcat(Request, Headers);
  189.     if (ClientDataSize) 
  190.     {
  191.         sprintf(ClientData, "Content-Length: %drn", ClientDataSize);
  192.         strcat(Request, ClientData);
  193.     }
  194.     if ( fKeepAlive )
  195.     {
  196.         strcat(Request, "Connection: Keep-Alivern" );
  197.     }
  198.     if ( !AddAuthorizationHeader( Request + strlen(Request), achAuth, pchAuthData, pchUserName, pchPassword, &fNeedMoreData ) )
  199.     {
  200.         printf( "Authentication failedn" );
  201.         fSt = FALSE;
  202.         goto ex;
  203.     }
  204.     strcat(Request, CrLf);
  205.     RequestSize = strlen(Request);
  206.     Error =
  207.     send(
  208.         Socket,
  209.         Request,
  210.         RequestSize,
  211.         0);
  212.     if (Error != RequestSize) 
  213.     {
  214.         printf("Error in client send = %d, %dn", Error, GetLastError());
  215.         fSt = FALSE;
  216.         goto ex;
  217.     }
  218.     if (ClientDataSize) 
  219.     {
  220.         memset( ClientData, ' ', ClientDataSize );
  221.         //
  222.         // Send the client data
  223.         //
  224.         Error =
  225.         send(
  226.             Socket,
  227.             ClientData,
  228.             ClientDataSize,
  229.             0);
  230.         if ( (DWORD)Error != ClientDataSize) 
  231.         {
  232.             printf("Error in client send = %d, %dn", Error, GetLastError());
  233.             fSt = FALSE;
  234.             goto ex;
  235.         }
  236.     }
  237.     // parse status & header
  238.     cLen = (DWORD)-1;
  239.     fInHeader = TRUE;
  240.     fServerKeepAlive = FALSE;
  241.     fNeedAuthenticate = FALSE;
  242.     for ( pH = ReceiveBuffer, fStatusLine = TRUE ; fInHeader ; )
  243.     {
  244.         cRec = recv( Socket, pH, ReceiveBuffer+sizeof(ReceiveBuffer)-pH, 0 );
  245.         if ( cRec <= 0 )
  246.         {
  247.             closesocket( Socket );
  248.             Socket = INVALID_SOCKET;
  249.             break;
  250.         }
  251.         pH[ cRec ] = '';
  252.         // Iterate on header fields
  253.         while ( pN = strstr(pH, "rn" ) )
  254.         {
  255.             *pN = '';
  256.             if ( DisplayHeaders )
  257.             {
  258.                 printf( "%sn", pH );
  259.             }
  260.             if ( fStatusLine )
  261.             {
  262.                 // This is the status line, decode status
  263.                 SkipNonWhite( &pH );
  264.                 SkipWhite( &pH );
  265.                 Status = atoi( pH );
  266.                 if ( Status == 401 )
  267.                 {
  268.                     fNeedAuthenticate = TRUE;
  269.                 }
  270.                 fStatusLine = FALSE;
  271.             }
  272.             else if ( pN == pH )    // end of header fields
  273.             {
  274.                 if ( hnd != EOF )
  275.                     write( hnd, pH+2, ReceiveBuffer+cRec-pH-2 );
  276.                 cLen -= ( ReceiveBuffer+cRec-pH-2 );
  277.                 fInHeader = FALSE;
  278.                 break;
  279.             }
  280.             else if ( !strnicmp( pH, HD_AUTHENTICATE, sizeof(HD_AUTHENTICATE)-1 ) )
  281.             {
  282.                 SkipNonWhite( &pH );
  283.                 SkipWhite( &pH );
  284.                 // check if we are already in the authentication sequence
  285.                 if ( !IsInAuthorizationSequence() )
  286.                 {
  287.                     // append to list of supported authentication methods
  288.                     strcpy( paAuth, pH );
  289.                     paAuth += strlen( pH ) + 1;
  290.                 }
  291.                 else
  292.                 {
  293.                     // store pointer to authenticate blob
  294.                     SkipNonWhite( &pH );
  295.                     SkipWhite( &pH );
  296.                     pchAuthData = pH;
  297.                 }
  298.             }
  299.             else if ( !strnicmp( pH, HD_LENGTH, sizeof(HD_LENGTH)-1 ) )
  300.             {
  301.                 // get content length
  302.                 SkipNonWhite( &pH );
  303.                 SkipWhite( &pH );
  304.                 cLen = atoi( pH );
  305.             }
  306.             else if ( !strnicmp( pH, HD_CONNECTION, sizeof(HD_CONNECTION)-1 ) )
  307.             {
  308.                 // check for keep-alive flag
  309.                 SkipNonWhite( &pH );
  310.                 SkipWhite( &pH );
  311.                 if ( !strnicmp( pH, "Keep-Alive", sizeof("Keep-Alive")-1 ) )
  312.                     fServerKeepAlive = TRUE;
  313.             }
  314.             pH = pN + 2;
  315.         }
  316.     }
  317.     // add final delimiter to list of supported authentication methods
  318.     if ( !IsInAuthorizationSequence() && fNeedAuthenticate )
  319.     {
  320.         *paAuth = '';
  321.         // Insure specified methods are supported localy
  322.         if ( !ValidateAuthenticationMethods( achAuth, pszPref ) )
  323.         {
  324.             // None of the server specified authentication methods
  325.             // are supported localy.
  326.             SetLastError( ERROR_ACCESS_DENIED );
  327.             fprintf( stderr, "No supported authentication methodn" );
  328.             fSt = FALSE;
  329.             goto ex;
  330.         }
  331.     }
  332.     // read message body
  333.     if ( Socket != INVALID_SOCKET )
  334.     {
  335.         for ( ; cLen ; )
  336.         {
  337.             if ( (cToRead = sizeof(ReceiveBuffer)) > cLen )
  338.                 cToRead = cLen;
  339.             cRec = recv( Socket, ReceiveBuffer, cToRead, 0 );
  340.             if ( cRec <= 0 )
  341.             {
  342.                 closesocket( Socket );
  343.                 Socket = INVALID_SOCKET;
  344.                 break;
  345.             }
  346.             if ( hnd != EOF )
  347.                 write( hnd, ReceiveBuffer, cRec );
  348.             cLen -= cRec;
  349.         }
  350.     }
  351.     if ( !fServerKeepAlive )
  352.     {
  353.         if ( IsInAuthorizationSequence() )
  354.         {
  355.             fprintf( stderr, "Authentication rejected by servern" );
  356.             fNeedAuthenticate = FALSE;  // authentication failed
  357.         }
  358.         closesocket( Socket );
  359.         Socket = INVALID_SOCKET;
  360.     }
  361.     if ( fNeedAuthenticate )
  362.     {
  363.         fKeepAlive = TRUE;
  364.         goto again;
  365.     }
  366.     if ( Socket != INVALID_SOCKET )
  367.         closesocket(Socket);
  368.     fSt = Status == 200;
  369. ex:
  370.     TerminateAuthorizationHeader();
  371.     if ( hnd != EOF )
  372.         close( hnd );
  373.     return fSt;
  374. }