home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / OTSimpleDownloadHTTP / OTSimpleDownloadHTTPTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  6.2 KB  |  247 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        OTSimpleDownloadHTTPTest.c
  3.  
  4.     Contains:    A test program for the simple HTTP download sample.
  5.  
  6.     Written by: Quinn "The Eskimo!"    
  7.  
  8.     Copyright:    Copyright © 1997-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 7/23/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23. #include <DriverServices.h>
  24. /////////////////////////////////////////////////////////////////////
  25. // The OT debugging macros in <OTDebug.h> require this variable to
  26. // be set.
  27. #include <TextUtils.h>
  28.  
  29. #ifndef qDebug
  30. #define qDebug    1
  31. #endif
  32.  
  33. /////////////////////////////////////////////////////////////////////
  34. // Pick up all the standard OT stuff.
  35.  
  36. #include <OpenTransport.h>
  37.  
  38. /////////////////////////////////////////////////////////////////////
  39. // Pick up all the OT TCP/IP stuff.
  40.  
  41. #include <OpenTptInternet.h>
  42.  
  43. /////////////////////////////////////////////////////////////////////
  44. // Pick up the OTDebugBreak and OTAssert macros.
  45.  
  46. #include <OTDebug.h>
  47.  
  48. /////////////////////////////////////////////////////////////////////
  49. // OTDebugStr is not defined in any OT header files, but it is
  50. // exported by the libraries, so we define the prototype here.
  51.  
  52. extern pascal void OTDebugStr(const char* str);
  53.  
  54. #include <OpenTptInternet.h>
  55. #include <PLStringFuncs.h>
  56. #include <Threads.h>
  57. #include <Files.h>
  58.  
  59. #include <string.h>
  60. #include <stdio.h>
  61. #include <ctype.h>
  62.  
  63. #include "OTSimpleDownloadHTTP.h"
  64.  
  65. enum {
  66.     kNotHTTPURLErr = -666,
  67.     kWhatImplementationErr = -667
  68. };
  69.  
  70. enum {
  71.     kDownloadSimple,
  72.     kDownloadFaster
  73. };
  74.  
  75. static OSStatus DownloadURL(const char *urlString)
  76. {
  77.     OSStatus err;
  78.     size_t hostCharCount;
  79.     char hostName[256];
  80.     Str255 tickCountString;
  81.     Str255 destFileName;
  82.     FSSpec destFSSpec;
  83.     short destFileRefNum;
  84.     char httpGetCommand[256];
  85.     OTTimeStamp startTime;
  86.     UInt32 timeToDownload;
  87.     long fileSize;
  88.     
  89.     err = noErr;
  90.     // First check that the urlString begins with "http://"
  91.     if ( strspn(urlString, "http://") != strlen("http://") ) {
  92.         err = kNotHTTPURLErr;
  93.     }
  94.  
  95.     // Now skip over the "http://" and extract the host name.
  96.     if (err == noErr) {
  97.         // Skip over the "http://".
  98.         urlString += strlen("http://");
  99.         
  100.         // Count the characters before the next slash.
  101.         hostCharCount = strcspn(urlString, "/");
  102.         
  103.         // Extract those characters from the URL into hostName
  104.         //  and then make sure it's null terminated.
  105.         (void) strncpy(hostName, urlString, hostCharCount);
  106.         hostName[hostCharCount] = 0;
  107.         urlString += hostCharCount;
  108.         
  109.         // Add a ":80" to the host name if necessary.
  110.         if ( strchr( hostName, ':' ) == nil ) {
  111.             strcat( hostName, ":80" );
  112.         }
  113.  
  114.         if (err == noErr) {
  115.             NumToString(TickCount(), tickCountString);
  116.             PStrCopy(destFileName, "\pSimpleDownload#");
  117.             PStrCat(destFileName, tickCountString);
  118.             (void) FSMakeFSSpec(0, 0, destFileName, &destFSSpec);
  119.             (void) FSpCreate(&destFSSpec, 'R*ch', 'TEXT', 0);
  120.             err = FSpOpenDF(&destFSSpec, fsRdWrPerm, &destFileRefNum);
  121.             if (err != noErr) {
  122.                 destFileRefNum = 0;
  123.             }
  124.         }
  125.         
  126.         if (err == noErr) {
  127.             // Now place the URL into the HTTP command that we send to DownloadHTTPSimple.
  128.             if ( *urlString == 0 ) {
  129.                 urlString = "/";
  130.             }
  131.             (void) sprintf(httpGetCommand, "GET %s HTTP/1.0%c%c%c%c", urlString, 13, 10, 13, 10);
  132.             printf("Calling DownloadHTTPXxxx(“%s”, “%s”, %04x).\n", hostName, urlString, destFileRefNum);
  133.             
  134.             OTGetTimeStamp(&startTime);
  135.             err = DownloadHTTPSimple(hostName, httpGetCommand, destFileRefNum);
  136.             timeToDownload = OTElapsedMicroseconds(&startTime);
  137.         }
  138.  
  139.         if (err == noErr) {
  140.             OTAssert( "DownloadURL: GetFPos failed", GetFPos(destFileRefNum, &fileSize) == noErr);
  141.             printf("Bytes downloaded: %d.\n", fileSize);
  142.             printf("Time to download: %dus.\n", timeToDownload);
  143.             printf("Bytes per second: %f.\n", (float) fileSize / (((float) timeToDownload) / 1000000.0) );
  144.         }
  145.  
  146.         // Clean up.
  147.         if (destFileRefNum != 0) {
  148.             (void) FSClose(destFileRefNum);
  149.         }
  150.         if (err != noErr) {
  151.             //(void) FSpDelete(&destFSSpec);
  152.         }
  153.  
  154.     }
  155.  
  156.     return (err);
  157. }
  158.  
  159. static UInt32 gLastPrinted = 0;
  160.  
  161. static pascal OSStatus ProgressThread(void *junkParam)
  162. {
  163.     #pragma unused(junkParam)
  164.     OSStatus junk;
  165.  
  166.     while (true) {
  167.         if ( TickCount() > (gLastPrinted + 60) ) {
  168.             printf(".");
  169.             fflush(stdout);
  170.             gLastPrinted = TickCount();
  171.         }
  172.         junk = YieldToAnyThread();
  173.         OTAssert("ProgressThread: YieldToAnyThread failed", junk == noErr);
  174.     }
  175.  
  176.     return (noErr);    
  177. }
  178.  
  179. static const char *defaultURLs[10] = {
  180. "http://www.apple.com",
  181. "http://www.apple.com/developer/",
  182. "http://developer.apple.com/dev/opentransport/",
  183. "http://developer.apple.com/technotes/index.html",
  184. "",
  185. "",
  186. "",
  187. "",
  188. "",
  189. ""
  190. };
  191.  
  192. void main(void)
  193. {
  194.     OSStatus err;
  195.     OSStatus junk;
  196.     char urlString[256];
  197.     UInt32 i;
  198.     ThreadID progressThread;
  199.     
  200.     printf("Hello Cruel World!\n");
  201.     printf("\n");
  202.     printf("OTDownloadHTTP!\n");
  203.     printf("-- Downloads a URL using OT's thread support\n");
  204.     printf("-- or using notifiers.\n");
  205.     printf("\n");
  206.  
  207.     err = InitOpenTransport();
  208.     if (err == noErr) {
  209.         
  210.         for (i = 0; i < 10; i++) {
  211.             if ( *defaultURLs[i] != 0 ) {
  212.                 printf("%d> %s\n", i, defaultURLs[i]);
  213.             }
  214.         }
  215.         printf("\n");
  216.         printf("Enter a URL (or type a number from the above list):\n");
  217.         gets(urlString);
  218.         if ( strlen(urlString) == 1 && isdigit(urlString[0])) {
  219.             strcpy( urlString, defaultURLs[ urlString[0] - '0' ] );
  220.         }
  221.         if ( urlString[0] == 0 ) {
  222.             strcpy( urlString, defaultURLs[0] );
  223.         }
  224.         err = NewThread(kCooperativeThread,
  225.                             (ThreadEntryProcPtr) ProgressThread, nil,
  226.                             0, kCreateIfNeeded,
  227.                             nil,
  228.                             &progressThread);
  229.         if (err == noErr) {
  230.             err = DownloadURL(urlString);
  231.             junk = DisposeThread(progressThread, nil, true);
  232.             OTAssert("main: DisposeThread failed", junk == noErr);
  233.         }
  234.         
  235.         CloseOpenTransport();
  236.     }
  237.     
  238.     if (err == noErr) {
  239.         printf("Success.\n");
  240.     } else {
  241.         printf("Failed with error %d.\n", err);
  242.     }    
  243.     printf("Done.  Press command-Q to Quit.\n");
  244. }
  245.  
  246.  
  247.