HttpRequest.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: HttpRequest.cpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 #include "HttpRequest.hpp" 00045 00046 00047 /***********************************************************************/ 00048 HttpRequest::HttpRequest(const char *url) 00049 { 00050 uri = new Url(url); 00051 if (uri->getPort() == 0) 00052 uri->setPort(80); //default http port 00053 00054 00055 contentLength = 0; 00056 contentType = mime_unknown; 00057 headerbuf = NULL; 00058 contentStart = NULL; 00059 } 00060 00061 00062 /***********************************************************************/ 00063 HttpRequest::~HttpRequest() { 00064 closeSock(); 00065 } 00066 00067 00068 00069 /***********************************************************************/ 00070 int HttpRequest::continueReceive(char *recbuffer, int size) { 00071 int num; 00072 int realsize; 00073 if (headerbuf && contentStart) { 00074 num = bufend - (contentStart - headerbuf); 00075 realsize = MIN(num,size); 00076 memcpy(recbuffer, contentStart, realsize); 00077 contentStart+=realsize; 00078 00079 if (contentStart == headerbuf+bufend) { 00080 //all initial payload bytes are forwarded 00081 delete [] headerbuf; 00082 contentStart = NULL; 00083 bufend = 0; 00084 } 00085 return realsize; 00086 } 00087 else { 00088 num = recv(sock, recbuffer, size, 0); 00089 if (num == 0) //regular end of connection 00090 return -1; 00091 else 00092 return num; //may also be -1 on error! 00093 } 00094 } 00095 00096 00097 /***********************************************************************/ 00098 bool HttpRequest::makeHttpRequest() 00099 { 00100 00101 headerbuf = new char[MAX_HEADERS_SIZE]; 00102 int len; 00103 00104 if (createSocket(uri->getServerName(), uri->getPort())) { 00105 //send request to the server 00106 00107 char *msg = new char[MAX_HEADERS_SIZE]; 00108 strcpy(msg, "GET "); 00109 strcat(msg, uri->getPath()); 00110 strcat(msg, " HTTP/1.0\r\n\r\n"); 00111 //dprintf_full("makeHttpRequest #%s#\n",msg); 00112 send(sock, msg, strlen(msg), 0); 00113 delete [] msg; 00114 00115 //wait for response 00116 memset(headerbuf, 0, MAX_HEADERS_SIZE); 00117 00118 00119 len = 0; bufend = 0; 00120 do { 00121 len = recv(sock, headerbuf+bufend, MAX_HEADERS_SIZE-bufend-1, 0); 00122 // dprintf_full("makeHttpRequest read #%s# RET %i\n",headerbuf,len); 00123 /* 00124 for (int i=0; i < len; i++) 00125 printf("%c",*((char*)(headerbuf+bufend+i))); 00126 printf("%c\n"); 00127 */ 00128 00129 bufend += len; 00130 contentStart = strstr(headerbuf, "\r\n\r\n"); 00131 if (contentStart) 00132 contentStart+=4; 00133 } while ((len > 0) && !contentStart); 00134 00135 00136 if (len != -1) { 00137 //search for HTTP 200 OK 00138 if (strstr(headerbuf, "HTTP") != NULL && strstr(headerbuf, "200 OK") != NULL) { 00139 00140 char *posFound = NULL; 00141 00142 //search for content-length 00143 if ((posFound = strstr(headerbuf, "Content-Length: ")) != NULL) { 00144 contentLength = atoi(posFound + strlen("Content-Length: ")); 00145 } else { 00146 dprintf_err("HttpRequest::makeHttpRequest(): content-length in #%s# not found. setting to -1\n",headerbuf); 00147 contentLength = -1; 00148 } 00149 00150 //search for content-type 00151 if ((posFound = strstr(headerbuf, "Content-Type: ")) != NULL) { 00152 char *mime = posFound + strlen("Content-Type: "); 00153 for (int i=0; i < NUM_KNOWN_HTTP_MIMETYPES; i++) { 00154 if (strstr(mime,HttpMimeTypeStrings[i]) != NULL) { 00155 contentType = (HttpMimeType)i; 00156 break; 00157 } 00158 } 00159 } else { 00160 dprintf_err("HttpRequest::makeHttpRequest(): content-type in #%s# not found. setting to application/octetstream\n",headerbuf); 00161 contentType = mime_unknown; 00162 } 00163 00164 return true; 00165 } 00166 } 00167 00168 dprintf_err_fatal("HttpRequest::makeHttpRequest: file not found on server!\n"); 00169 return false; 00170 } else 00171 return false; 00172 } 00173 00174 00175 /***********************************************************************/ 00176 bool HttpRequest::isIPNumber(const char *host) { 00177 assert(host); 00178 for (unsigned int i = 0; i < strlen(host); i++) { 00179 if (!((host[i] >= '0' && host[i] <= '9') || host[i] == '.')) return false; 00180 } 00181 return true; 00182 } 00183 00184 00185 00186 /***********************************************************************/ 00187 bool HttpRequest::createSocket(const char *host, int port) 00188 { 00189 struct hostent *hp; 00190 struct sockaddr_in sin; 00191 00192 #ifndef WINCE 00193 /* 00194 if (isIPNumber(host)) { 00195 unsigned int addr = inet_addr(host); 00196 hp = gethostbyaddr((char*)&addr, 4, AF_INET); 00197 } else 00198 */ 00199 { 00200 hp = gethostbyname(host); 00201 } 00202 00203 if (!hp) 00204 { 00205 int myerr = 0; 00206 dprintf_err_fatal("HttpRequest::createSocket: Cannot resolve host '%s' (err=%d)\n", host, myerr); 00207 return false; 00208 } 00209 #endif 00210 00211 00212 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 00213 { 00214 dprintf_err_fatal("HttpRequest::createSocket: Error on socket create (%s:%d)\n", host, port); 00215 return false; 00216 } 00217 00218 sin.sin_family = AF_INET; 00219 sin.sin_port = htons(port); 00220 #ifndef WINCE 00221 memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); 00222 #else 00223 unsigned long addr = inet_addr(host); 00224 sin.sin_addr.S_un.S_addr = addr; 00225 #endif 00226 00227 00228 00229 if (connect(sock, (struct sockaddr*) &sin, sizeof(struct sockaddr)) != 0) 00230 { 00231 dprintf_err_fatal("HttpRequest::createSocket: Error on socket connect (%s:%d)\n", host, port); 00232 closeSock(); 00233 return false; 00234 } 00235 00236 return true; 00237 } 00238 00239 00240 00241 /***********************************************************************/ 00242 void HttpRequest::closeSock() 00243 { 00244 if (sock != 0) { 00245 #ifdef WIN32 00246 closesocket(sock); 00247 #else 00248 close(sock); 00249 #endif 00250 } 00251 }