unsigned SIM::fetch(TCPClient *cl, const char *url, Buffer *postData, const char *headers) { FetchClient *client = new FetchClient(cl, url, postData, headers); if (client->id()) return client->id(); delete client; return 0; }
unsigned SIM::fetch(const char *url, Buffer *postData, const char *headers, bool bRedirect) { #ifdef WIN32 bool bState; if (get_connection_state(bState)) getSocketFactory()->setActive(bState); #endif FetchClient *client = new FetchClient(url, postData, headers, bRedirect); if (client->id()) return client->id(); delete client; return 0; }
void FetchClientPrivate::write_ready() { if (m_postSize == 0) return; char buff[4096]; unsigned tail = m_postSize; if (tail > sizeof(buff)) tail = sizeof(buff); const char *data = m_client->read_data(buff, tail); if (data == NULL){ m_socket->error_state("Read error"); return; } m_postSize -= tail; m_socket->writeBuffer.pack(data, tail); m_socket->write(); if (m_speed){ m_sendSize += tail; time_t now; time(&now); if ((unsigned)now != m_sendTime){ m_sendTime = now; m_sendSize = 0; } if (m_sendSize > (m_speed << 18)){ m_socket->pause(1); return; } } }
bool FetchClientPrivate::error_state(const char *err, unsigned) { if (m_state == None) return false; if (m_state == Redirect){ if (m_socket){ delete m_socket; m_socket = NULL; } m_code = 0; m_hIn = ""; m_state = None; _fetch(); return false; } if ((m_state != Done) && ((m_state != Data) || (m_size != UNKNOWN_SIZE))){ m_code = 0; log(L_DEBUG, "HTTP: %s", err); } m_bDone = true; m_state = None; if (m_socket) m_socket->close(); return m_client->done(m_code, m_data, m_hIn.c_str()); }
void FetchClientPrivate::packet_ready() { if (m_socket->readBuffer.readPos() == m_socket->readBuffer.writePos()) return; for (;;){ if (m_state == Data){ unsigned size = m_socket->readBuffer.writePos() - m_socket->readBuffer.readPos(); if (size){ if (!m_client->write_data(m_socket->readBuffer.data(m_socket->readBuffer.readPos()), size)){ m_socket->error_state("Write error"); return; } } m_received += size; if (m_received >= m_size){ m_state = Done; m_socket->error_state(""); return; } m_socket->readBuffer.init(0); m_socket->readBuffer.packetStart(); return; } log_packet(m_socket->readBuffer, false, HTTPPacket); string line; string opt; if (!read_line(line)){ m_socket->readBuffer.init(0); m_socket->readBuffer.packetStart(); return; } switch (m_state){ case None: #ifdef USE_OPENSSL case SSLConnect: #endif if (getToken(line, ' ').substr(0, 5) != "HTTP/"){ m_socket->error_state("Bad HTTP answer"); return; } m_code = atol(getToken(line, ' ').c_str()); m_state = Header; break; case Header: if (line.empty()){ m_state = Data; break; } m_hIn += line; m_hIn += '\x00'; opt = getToken(line, ':'); if (opt == "Content-Length"){ const char *p; for (p = line.c_str(); *p; p++) if (*p != ' ') break; m_size = atol(p); } if ((opt == "Location") && m_bRedirect){ const char *p; for (p = line.c_str(); *p; p++) if (*p != ' ') break; string proto; string host; string user; string pass; string uri; string extra; unsigned short port; if (!FetchClient::crackUrl(p, proto, host, port, user, pass, uri, extra)){ FetchClient::crackUrl(m_uri.c_str(), proto, host, port, user, pass, uri, extra); extra = ""; if (*p == '/'){ uri = p; }else{ int n = uri.find_last_of('/'); uri = uri.substr(0, n + 1); uri += p; } } m_uri = proto; m_uri += "://"; m_uri += host; m_uri += ":"; m_uri += number(port); m_uri += uri; if (!extra.empty()){ m_uri += "?"; m_uri += extra; } m_state = Redirect; m_socket->close(); m_socket->error_state(""); return; } break; default: break; } } }
void FetchClientPrivate::connect_ready() { #ifdef USE_OPENSSL if ((m_state == None) & m_bHTTPS){ m_socket->setRaw(true); m_socket->readBuffer.init(0); HTTPSClient *https = new HTTPSClient(m_socket->socket()); if (!https->init()){ m_socket->error_state("Can't initialize HTTPS"); return; } m_state = SSLConnect; m_socket->setSocket(https); https->connect(); https->process(); return; } #endif log(L_DEBUG, "HTTP connect ready"); m_socket->setRaw(true); m_socket->writeBuffer.packetStart(); string proto; string host; string user; string pass; string uri; string extra; unsigned short port; FetchClient::crackUrl(m_uri.c_str(), proto, host, port, user, pass, uri, extra); if (!extra.empty()){ uri += "?"; uri += extra; } unsigned postSize = m_client->post_size(); m_socket->writeBuffer << ((postSize != NO_POSTSIZE) ? "POST " : "GET ") << uri.c_str() << " HTTP/1.0\r\n"; if (!findHeader("Host")) m_socket->writeBuffer << "Host: " << host.c_str() << "\r\n"; if (!findHeader("User-Agent")) m_socket->writeBuffer << "User-Agent: " << FetchManager::manager->user_agent.c_str() << "\r\n"; if (!findHeader("Authorization") && !user.empty()) m_socket->writeBuffer << "Authorization: basic " << basic_auth(user.c_str(), pass.c_str()).c_str() << "\r\n"; if (postSize != NO_POSTSIZE){ if (!findHeader("Content-Length")) m_socket->writeBuffer << "Content-Length: " << number(postSize).c_str() << "\r\n"; m_postSize = postSize; } for (HEADERS_MAP::iterator it = m_hOut.begin(); it != m_hOut.end(); ++it){ m_socket->writeBuffer << (*it).first.c_str() << ": " << (*it).second.c_str() << "\r\n"; } m_socket->writeBuffer << "\r\n"; log_packet(m_socket->writeBuffer, true, HTTPPacket); m_socket->write(); m_socket->readBuffer.init(0); m_socket->readBuffer.packetStart(); }