C++ Get MimeType from URL

  1. /* ========================================= *
  2.  *          (c) 2012 Wolf Officious          *
  3.  *                                           *
  4.  *       GET HTTP Content-Type Example       *
  5.  * ========================================= */
  6.  
  7.  
  8. #include <string>
  9. #include <iostream>
  10. #include <stdio.h>
  11. #include <stdlib.h>     // system()
  12. #include <WinSock2.h>   // Windows Socket v2
  13. #include <WinDef.h>     // Windows Definitions (WORD, BYTE, LOBYTE, HIBYTE, ...)
  14.  
  15. using namespace std;
  16.  
  17. #define BUFSIZE         1024
  18.  
  19. string FindURLContentType(string URL);
  20.  
  21. int main(int argc, char* argv[])
  22. {
  23.     if(argc < 2)
  24.     {
  25.         cout << "Incorect syntax!";
  26.         return -10;
  27.     }
  28.  
  29.     string result = FindURLContentType(argv[1]);
  30.     cout << result;
  31.  
  32.     if(result.find("ERR", 0, 3) != string::npos)
  33.     {
  34.         int ret_val = atoi(string(result, 3, 1).c_str());
  35.         return -(ret_val);
  36.     }
  37.  
  38.     return 0;
  39. }
  40.  
  41. string FindURLContentType(string URL)
  42. {
  43.     // Initialize WinSock ---->>
  44.     WORD wVersionRequested = WINSOCK_VERSION; // MAKEWORD(2,0);
  45.     WSADATA data;
  46.  
  47.     if(WSAStartup(wVersionRequested, &data) != NULL) // Startup WinSock
  48.     {
  49.         return "ERR1: (WSA: INIT FAILED -> STARTUP)";
  50.     }
  51.  
  52.     if(LOBYTE(data.wVersion) != LOBYTE(wVersionRequested) ||
  53.        HIBYTE(data.wVersion) != HIBYTE(wVersionRequested)) // Version Check
  54.     {
  55.         WSACleanup(); // Cleanup WinSock
  56.         return "ERR2: (WSA: INIT FAILED -> VERSION)";
  57.     }
  58.     // <<---- Initialize WinSock
  59.  
  60.     // Parse Input URL ---->>
  61.     int begHost = 0;
  62.     int endHost = 0;
  63.  
  64.     if((begHost = URL.find("http://")) != string::npos)
  65.         begHost += 7;
  66.     else
  67.         begHost = 0;
  68.  
  69.     if((endHost = URL.find("/", begHost)) == string::npos)
  70.     {
  71.         endHost = URL.size();
  72.         URL += "/";
  73.     }
  74.  
  75.     string URLhost(URL, begHost, endHost-begHost);
  76.     string URLtail(URL, endHost, URL.size());
  77.  
  78.     /* DEBUG
  79.     cout << "HOST: " << URLhost << endl;
  80.     cout << "TAIL: " << URLtail << endl;*/
  81.     // <<---- Parse Input URL
  82.  
  83.     // Initialize & Setup Socket ---->>
  84.     SOCKET mySocket; // Socket Handler
  85.     if((mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) // Open TCP Socket
  86.     {
  87.         WSACleanup(); // Cleanup WinSock
  88.         return "ERR3: (SOCKET: INVALID_SOCKET)";
  89.     }
  90.  
  91.     hostent *H = gethostbyname(URLhost.c_str());
  92.     if(H == NULL)
  93.     {
  94.         WSACleanup(); // Cleanup WinSock
  95.         return "ERR4: (HOST: HOSTNAME FIND FAILED)";
  96.     }
  97.  
  98.     sockaddr_in serverSock;                     // Socket Structure
  99.     serverSock.sin_family = AF_INET;            // Socket Family
  100.     serverSock.sin_port   = htons(80);          // Socket Port
  101.     serverSock.sin_addr   = (*(in_addr *)H->h_addr_list[0]);
  102.     if(connect(mySocket, (sockaddr *)&serverSock, sizeof(serverSock)) == SOCKET_ERROR) // Connect
  103.     {
  104.         closesocket(mySocket); // Close Socket
  105.         WSACleanup(); // Cleanup WinSock
  106.         return "ERR5: (CONNECT: SOCKET_ERROR)";
  107.     }
  108.     // <<---- Initialize & Setup Socket
  109.  
  110.     // Send ---->>
  111.     string request = "HEAD " + URLtail + " HTTP/1.1\nhost: " + URLhost + "\n\n"; // TCP Request (question)
  112.     if(send(mySocket, request.c_str(), request.size() + 1, 0) == SOCKET_ERROR) // Send Request (question)
  113.     {
  114.         closesocket(mySocket); // Close Socket
  115.         WSACleanup(); // Cleanup WinSock
  116.         return "ERR6: (SEND: SOCKET_ERROR)";
  117.     }
  118.     // <<---- Send
  119.  
  120.     // Receive ---->>
  121.     char buf[BUFSIZE];
  122.     if(recv(mySocket, buf, BUFSIZE - 1, 0) == SOCKET_ERROR) // TCP Receive (answer)
  123.     {
  124.         closesocket(mySocket); // Close Socket
  125.         WSACleanup(); // Cleanup WinSock
  126.         return "ERR7: (RECV: SOCKET_ERROR)";
  127.     }
  128.     string header = buf; // Copy buffer to String
  129.     // <<---- Receive
  130.  
  131.     // Cleanup & Close Socket ---->>
  132.     closesocket(mySocket); // Close Socket
  133.     WSACleanup(); // Cleanup WinSock
  134.     // <<---- Cleanup & Close Socket
  135.  
  136.     // Parse Return Code ---->>
  137.     if(header.find("HTTP/1.1 200 OK") == string::npos)
  138.     {
  139.         if(header.find("HTTP/1.1 301") != string::npos)
  140.         {
  141.             int a = header.find("Location: ") + 10;
  142.             int b = header.find('\n',  a);
  143.             string URLredirect(header, a, b-a);
  144.             return FindURLContentType(URLredirect);
  145.         }
  146.         else
  147.         {
  148.             int a = header.find("HTTP/1.1 ");
  149.             if(a != string::npos)
  150.             {
  151.                 return "ERR8: (HTTP SERVER RETURNS CODE " + string(header, a+9, 3) + ")";
  152.             }
  153.         }
  154.  
  155.         //cout << header; // DEBUG
  156.         return "ERR8: (HTTP SERVER RETURNS UNKNOWN CODE)";
  157.     }
  158.     // <<---- Parse Return Code
  159.  
  160.     // Parse Content-Type ---->>
  161.     int position;
  162.     string mimetype;
  163.     bool isFindError = true;
  164.  
  165.     if((position = header.find("Content-Type: ")) != string::npos)
  166.     {
  167.         position += 14;
  168.         for(unsigned int i = position; i < header.size(); ++i)
  169.         {
  170.             if(header.c_str()[i] == '\r' ||
  171.                header.c_str()[i] == ';')
  172.                 break;
  173.  
  174.             mimetype += header.c_str()[i];
  175.         }
  176.         if(!mimetype.empty())
  177.         {
  178.             isFindError = false;
  179.         }
  180.     }
  181.  
  182.     if(isFindError)
  183.     {
  184.         return "ERR9: (PARSE: CANNOT FIND CONTENT-TYPE)";
  185.     }
  186.     // <<---- Parse Content-Type
  187.  
  188.     return mimetype;
  189. }
  190.  

Odpověď na kód "C++ Get MimeType from URL"

Zde můžete upravit/odpovědět na tento kód (touto akcí vložíte další kód, neupravíte stávající)