00001 /*!@file Devices/HTTPClient.C HTTP client for interfacing with http type devices */ 00002 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00006 // by the University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: Lior Elazary 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/HTTPClient.C $ 00036 // $Id: HTTPClient.C 12962 2010-03-06 02:13:53Z irock $ 00037 // 00038 00039 #include "Devices/HTTPClient.H" 00040 00041 #include "Component/OptionManager.H" 00042 #include "Component/ModelOptionDef.H" 00043 #include "Devices/DeviceOpts.H" 00044 #include "Util/log.H" 00045 #include "rutz/unixcall.h" // for rutz::unixcall::get_file_user_pid() 00046 00047 extern const ModelOptionCateg MOC_HTTP; 00048 00049 const ModelOptionCateg MOC_HTTP = { 00050 MOC_SORTPRI_2, "HTTPClient-Related Options" }; 00051 00052 static const ModelOptionDef OPT_HTTPClientHost = 00053 { MODOPT_ARG_STRING, "HostName", &MOC_HTTP, OPTEXP_CORE, 00054 "IP address of the server", 00055 "httpClient-hostname", '\0', "<name>", "localhost" }; 00056 00057 static const ModelOptionDef OPT_HTTPClientPort = 00058 { MODOPT_ARG(uint), "ServerPort", &MOC_HTTP, OPTEXP_CORE, 00059 "Port number of the server to use ", 00060 "httpClient-port", '\0', "<portnum>", "80" }; 00061 00062 // ###################################################################### 00063 HTTPClient::HTTPClient(OptionManager& mgr, 00064 const std::string& descrName, 00065 const std::string& tagName) : 00066 ModelComponent(mgr, descrName, tagName), 00067 itsHostName(&OPT_HTTPClientHost, this), 00068 itsPort(&OPT_HTTPClientPort, this), 00069 itsSocket(-1), 00070 itsRemote(NULL), 00071 itsConnected(false) 00072 { } 00073 00074 // ###################################################################### 00075 void HTTPClient::start1() 00076 { 00077 00078 } 00079 00080 // ###################################################################### 00081 void HTTPClient::openConnection() 00082 { 00083 if((itsSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 00084 LFATAL("Can't create TCP socket"); 00085 00086 std::string ipAddress = getIPAddress(itsHostName.getVal()); 00087 00088 LDEBUG("Connecting to %s", ipAddress.c_str()); 00089 00090 struct sockaddr_in * itsRemote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *)); 00091 itsRemote->sin_family = AF_INET; 00092 int res = inet_pton(AF_INET, ipAddress.c_str(), (void *)(&(itsRemote->sin_addr.s_addr))); 00093 if( res < 0) 00094 LFATAL("Can't set remote->sin_addr.s_addr"); 00095 else if(res == 0) 00096 LFATAL("%s is invalid.", ipAddress.c_str()); 00097 itsRemote->sin_port = htons(itsPort.getVal()); 00098 00099 //Connect to the host 00100 if(connect(itsSocket, (struct sockaddr *)itsRemote, sizeof(struct sockaddr)) < 0) 00101 { 00102 LINFO("Can not connect to %s", itsHostName.getVal().c_str()); 00103 itsConnected = false; 00104 } else { 00105 itsConnected = true; 00106 } 00107 00108 00109 } 00110 00111 00112 // ###################################################################### 00113 void HTTPClient::closeConnection() 00114 { 00115 if (itsSocket >= 0) 00116 close(itsSocket); 00117 } 00118 00119 00120 00121 // ###################################################################### 00122 std::string HTTPClient::getIPAddress(const std::string& hostName) 00123 { 00124 00125 int iplen = 15; //XXX.XXX.XXX.XXX 00126 char ip[15]; 00127 00128 struct hostent *hent; 00129 if((hent = gethostbyname(hostName.c_str())) == NULL) 00130 LFATAL("Can not resolve ip for %s", hostName.c_str()); 00131 00132 if(inet_ntop(AF_INET, (void *)hent->h_addr_list[0], ip, iplen) == NULL) 00133 LFATAL("Can not resolve ip for %s", hostName.c_str()); 00134 00135 std::string ipAddress = ip; 00136 return ipAddress; 00137 } 00138 00139 00140 // ###################################################################### 00141 void HTTPClient::stop2() 00142 { 00143 if (itsSocket >= 0) 00144 close(itsSocket); 00145 free(itsRemote); 00146 } 00147 00148 // ###################################################################### 00149 int HTTPClient::read(void* buffer, const int nbytes) 00150 { 00151 int n = 0; 00152 return n; 00153 } 00154 00155 00156 // ###################################################################### 00157 int HTTPClient::write(const void* buffer, const int nbytes) 00158 { 00159 int n = 0; 00160 return n; 00161 } 00162 00163 // ###################################################################### 00164 std::string HTTPClient::sendGetRequest(const std::string& request) 00165 { 00166 //Send a full http request 00167 std::string queryString = "GET " + request + " HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\nUser-Agent: httpClient\r\n\r\n"; 00168 00169 openConnection(); 00170 00171 std::string retData; 00172 if (itsConnected) 00173 { 00174 unsigned int sent = 0; 00175 while(sent < queryString.size()) 00176 { 00177 int ret = send(itsSocket, queryString.c_str()+sent, queryString.size()-sent, 0); 00178 if(ret == -1) 00179 LINFO("Can not send query"); 00180 sent += ret; 00181 } 00182 00183 retData = readData(); 00184 } 00185 00186 closeConnection(); 00187 00188 00189 return retData; 00190 } 00191 00192 // ###################################################################### 00193 std::string HTTPClient::sendPostRequest(const std::string& request, const char* data, long size) 00194 { 00195 //Send a full http request 00196 char dataSize[255]; 00197 sprintf(dataSize, "%lu", size); 00198 std::string queryString = "POST " + request + " HTTP/1.1\r\nHost: localhost\r\nConnection: Close\r\nUser-Agent: httpClient\r\nContent-Length: " + dataSize + "\r\n\r\n"; 00199 00200 openConnection(); 00201 00202 std::string retData; 00203 if (itsConnected) 00204 { 00205 unsigned int sent = 0; 00206 while(sent < queryString.size()) 00207 { 00208 int ret = send(itsSocket, queryString.c_str()+sent, queryString.size()-sent, 0); 00209 if(ret == -1) 00210 LINFO("Can not send query"); 00211 sent += ret; 00212 } 00213 00214 //Send Post Data 00215 sent = 0; 00216 while(sent < (unsigned int)(size)) 00217 { 00218 int ret = send(itsSocket, data+sent, size-sent, 0); 00219 if(ret == -1) 00220 LINFO("Can not send query"); 00221 sent += ret; 00222 } 00223 00224 //retData = readData(); 00225 } 00226 00227 closeConnection(); 00228 00229 00230 return retData; 00231 } 00232 00233 00234 00235 // ###################################################################### 00236 std::string HTTPClient::readData() 00237 { 00238 std::string data; 00239 00240 char buf[1024]; 00241 00242 int ret = 0; 00243 int htmlstart = 0; 00244 char * htmlcontent; 00245 while((ret = recv(itsSocket, buf, 1024, 0)) > 0) 00246 { 00247 buf[ret] = 0; 00248 if(htmlstart == 0) 00249 { 00250 htmlcontent = strstr(buf, "\r\n\r\n"); 00251 if(htmlcontent != NULL){ 00252 htmlstart = 1; 00253 data = htmlcontent + 4; 00254 } 00255 }else{ 00256 data = data + buf; 00257 } 00258 } 00259 00260 00261 return data; 00262 } 00263 00264 00265 00266 // ###################################################################### 00267 HTTPClient::~HTTPClient(void) 00268 { } 00269 00270 00271 00272 // ###################################################################### 00273 /* So things look consistent in everyone's emacs... */ 00274 /* Local Variables: */ 00275 /* indent-tabs-mode: nil */ 00276 /* End: */