RESTObject ContactsResource::post(std::string request, const RESTObject& posted) { // An ID is not allowed on POST, it will be returned // in the Locaiton: header if (!request.empty() && request != "/") throw HTTPException(400,"Invalid query"); Address addr; try { addr = Address::fromString(posted.properties["address"].asString()); } catch (...) { // TODO Create a proper exception class throw HTTPException(400,"Invalid address"); } GPSLocation loc(posted.properties["latitude"].asDouble(), posted.properties["longitude"].asDouble()); time_t expires = posted.properties["expires"].asUInt64(); contacts.insert(ContactsSet::Entry(addr,loc,expires)); // Return the object as required. RESTObject obj; obj.properties = posted.properties; // Set location to address obj.location = "/" + addr.toString(); return obj; }
StreamSocket HTTPClientSession::proxyConnect() { HTTPClientSession proxySession(getProxyHost(), getProxyPort()); proxySession.setTimeout(getTimeout()); SocketAddress targetAddress(getHost(), getPort()); HTTPRequest proxyRequest(HTTPRequest::HTTP_CONNECT, targetAddress.toString(), HTTPMessage::HTTP_1_1); HTTPResponse proxyResponse; proxyRequest.set("Proxy-Connection", "keep-alive"); proxyRequest.set("Host", getHost()); proxyAuthenticateImpl(proxyRequest); proxySession.setKeepAlive(true); proxySession.sendRequest(proxyRequest); proxySession.receiveResponse(proxyResponse); if (proxyResponse.getStatus() != HTTPResponse::HTTP_OK) throw HTTPException("Cannot establish proxy connection", proxyResponse.getReason()); return proxySession.detachSocket(); }
void HTTPSClientSession::connect(const SocketAddress& address) { if (getProxyHost().empty()) { SecureStreamSocket sss(socket()); if (_pContext->sessionCacheEnabled()) { sss.useSession(_pSession); } HTTPSession::connect(address); if (_pContext->sessionCacheEnabled()) { _pSession = sss.currentSession(); } } else { HTTPClientSession proxySession(address); proxySession.setHost(getProxyHost()); proxySession.setPort(getProxyPort()); proxySession.setTimeout(getTimeout()); SocketAddress targetAddress(getHost(), getPort()); HTTPRequest proxyRequest(HTTPRequest::HTTP_CONNECT, targetAddress.toString(), HTTPMessage::HTTP_1_1); HTTPResponse proxyResponse; proxyRequest.set("Proxy-Connection", "keep-alive"); proxyRequest.set("Host", getHost()); proxyAuthenticateImpl(proxyRequest); proxySession.setKeepAlive(true); proxySession.sendRequest(proxyRequest); proxySession.receiveResponse(proxyResponse); if (proxyResponse.getStatus() != HTTPResponse::HTTP_OK) throw HTTPException("Cannot establish proxy connection", proxyResponse.getReason()); StreamSocket proxySocket(proxySession.detachSocket()); SecureStreamSocket secureSocket = SecureStreamSocket::attach(proxySocket, getHost(), _pContext, _pSession); attachSocket(secureSocket); if (_pContext->sessionCacheEnabled()) { _pSession = secureSocket.currentSession(); } } }
RESTObject ContactsResource::get(std::string request) { if (!request.empty() && request != "/") throw HTTPException(400,"Invalid query"); RESTObject result; result.properties = Json::Value(Json::arrayValue); for (const ContactsSet::Entry& contact : contacts) { Json::Value contactInfo(Json::objectValue); contactInfo["address"] = contact.address.toString(); contactInfo["latitude"] = contact.location.lat; contactInfo["longitude"] = contact.location.lon; contactInfo["expires"] = (Json::UInt64) contact.expires; result.properties.append(contactInfo); } return result; }
std::istream* HTTPStreamFactory::open(const URI& uri) { poco_assert (uri.getScheme() == "http"); URI resolvedURI(uri); URI proxyUri; HTTPClientSession* pSession = 0; HTTPResponse res; bool retry = false; bool authorize = false; std::string username; std::string password; try { do { if (!pSession) { pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort()); if (proxyUri.empty()) pSession->setProxy(_proxyHost, _proxyPort); else pSession->setProxy(proxyUri.getHost(), proxyUri.getPort()); pSession->setProxyCredentials(_proxyUsername, _proxyPassword); } std::string path = resolvedURI.getPathAndQuery(); if (path.empty()) path = "/"; HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); if (authorize) { HTTPCredentials::extractCredentials(uri, username, password); HTTPCredentials cred(username, password); cred.authenticate(req, res); } pSession->sendRequest(req); std::istream& rs = pSession->receiveResponse(res); bool moved = (res.getStatus() == HTTPResponse::HTTP_MOVED_PERMANENTLY || res.getStatus() == HTTPResponse::HTTP_FOUND || res.getStatus() == HTTPResponse::HTTP_SEE_OTHER || res.getStatus() == HTTPResponse::HTTP_TEMPORARY_REDIRECT); if (moved) { resolvedURI.resolve(res.get("Location")); if (!username.empty()) { resolvedURI.setUserInfo(username + ":" + password); } throw URIRedirection(resolvedURI.toString()); } else if (res.getStatus() == HTTPResponse::HTTP_OK) { return new HTTPResponseStream(rs, pSession); } else if (res.getStatus() == HTTPResponse::HTTP_USEPROXY && !retry) { // The requested resource MUST be accessed through the proxy // given by the Location field. The Location field gives the // URI of the proxy. The recipient is expected to repeat this // single request via the proxy. 305 responses MUST only be generated by origin servers. // only use for one single request! proxyUri.resolve(res.get("Location")); delete pSession; pSession = 0; retry = true; // only allow useproxy once } else if (res.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED && !authorize) { authorize = true; retry = true; Poco::NullOutputStream null; Poco::StreamCopier::copyStream(rs, null); } else throw HTTPException(res.getReason(), uri.toString()); } while (retry); throw HTTPException("Too many redirects", uri.toString()); } catch (...) { delete pSession; throw; } }