📄 urlstorage.cxx
字号:
} // FIXME remove xxx/../, and /. return 1;}Boolean URLStorageManager::transformNeutral(StringC &str, Boolean fold, Messenger &) const{ if (fold) for (size_t i = 0; i < str.size(); i++) { Char c = str[i]; if (c <= (unsigned char)-1) str[i] = tolower(str[i]); } return 1;}#ifdef SP_HAVE_SOCKETSOCKET HttpSocketStorageObject::openHttp(const String<char> &host, unsigned short port, const StringC &hostStr, Messenger &mgr){#ifdef WINSOCK if (!winsockIniter.init(mgr)) return INVALID_SOCKET;#endif struct sockaddr_in sock; sock.sin_family = AF_INET; sock.sin_port = htons(port); if (isdigit((unsigned char)host[0])) { unsigned long n = inet_addr(host.data()); if (n == (unsigned long)-1) { ParentLocationMessenger(mgr).message(URLStorageMessages::invalidHostNumber, StringMessageArg(hostStr)); return INVALID_SOCKET; } sock.sin_addr.s_addr = n; } else { struct hostent *hp = gethostbyname(host.data()); if (!hp) { const MessageType1 *message; switch (h_errno) { case HOST_NOT_FOUND: message = &URLStorageMessages::hostNotFound; break; case TRY_AGAIN: message = &URLStorageMessages::hostTryAgain; break; case NO_RECOVERY: message = &URLStorageMessages::hostNoRecovery; break; case NO_DATA:#ifdef NO_ADDRESS#if NO_ADDRESS != NO_DATA case NO_ADDRESS:#endif#endif message = &URLStorageMessages::hostNoData; break; default:#ifdef WINSOCK ParentLocationMessenger(mgr).message(URLStorageMessages::hostOtherError, StringMessageArg(hostStr), WinsockMessageArg(h_errno)); return INVALID_SOCKET;#else message = &URLStorageMessages::hostUnknownError; break;#endif } ParentLocationMessenger(mgr).message(*message, StringMessageArg(hostStr)); return INVALID_SOCKET; } memcpy(&sock.sin_addr, hp->h_addr, hp->h_length); } SOCKET fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == INVALID_SOCKET) { ParentLocationMessenger(mgr).message(URLStorageMessages::cannotCreateSocket, SocketMessageArg(errnosocket)); return INVALID_SOCKET; } if (connect(fd, (struct sockaddr *)&sock, sizeof(sock)) == SOCKET_ERROR) { ParentLocationMessenger(mgr).message(URLStorageMessages::cannotConnect, StringMessageArg(hostStr), SocketMessageArg(errnosocket)); (void)closesocket(fd); return INVALID_SOCKET; } return fd;}HttpSocketStorageObject::HttpSocketStorageObject(SOCKET fd, Boolean mayRewind, const StringC &hostStr): RewindStorageObject(mayRewind, 0), hostStr_(hostStr), fd_(fd), eof_(0){}HttpSocketStorageObject::~HttpSocketStorageObject(){ if (fd_ != INVALID_SOCKET) (void)closesocket(fd_);}Boolean HttpSocketStorageObject::open(const String<char> &path, Messenger &mgr){ path_ = path; String<char> request; request.append("GET ", 4); request += path_; request += ' '; request.append("HTTP/1.0\r\n", 10); request.append("Accept: */*\r\n", 13); request.append("\r\n", 2); // FIXME check length of write if (writesocket(fd_, request.data(), request.size()) == SOCKET_ERROR) { ParentLocationMessenger(mgr).message(URLStorageMessages::writeError, StringMessageArg(hostStr_), SocketMessageArg(errnosocket)); (void)closesocket(fd_); fd_ = INVALID_SOCKET; return 0; } if (!readHeader(mgr)) { (void)closesocket(fd_); fd_ = INVALID_SOCKET; return 0; } return 1;}Boolean HttpSocketStorageObject::readHeader(Messenger &mgr){ String<char> buf; String<char> leftOver; if (!readLine(mgr, buf, leftOver)) return 0; buf += '\0'; const char *ptr = &buf[0]; int val; if (!parseStatus(ptr, val)) { if (buf.size() > 0) unread(buf.data(), buf.size() - 1); return 1; } if (val < 200 || val >= 300) { StringC reason; while (*ptr && *ptr != '\n' && *ptr != '\r') { reason += Char(*ptr); ptr++; } StringC pathStr; for (size_t i = 0; i < path_.size(); i++) pathStr += path_[i]; ParentLocationMessenger(mgr).message(URLStorageMessages::getFailed, StringMessageArg(hostStr_), StringMessageArg(pathStr), StringMessageArg(reason)); return 0; } for (;;) { if (!readLine(mgr, buf, leftOver)) return 0; if (buf.size() == 0 || buf[0] == '\r' || buf[0] == '\n') break; } if (leftOver.size()) unread(leftOver.data(), leftOver.size()); return 1;}// Status line must start with: "HTTP/" 1*DIGIT "." 1*DIGIT SP 3DIGIT SPBoolean HttpSocketStorageObject::parseStatus(const char *&ptr, int &val){ static const char ver[] = "HTTP/"; for (const char *v = ver; *v; v++, ptr++) if (*v != *ptr) return 0; if (!isdigit((unsigned char)*ptr)) return 0; do { ++ptr; } while (isdigit((unsigned char)*ptr)); if (*ptr != '.') return 0; ptr++; if (!isdigit((unsigned char)*ptr)) return 0; do { ++ptr; } while (isdigit((unsigned char)*ptr)); if (*ptr != ' ') return 0; ptr++; val = 0; for (int i = 0; i < 3; i++, ptr++) { if (!isdigit((unsigned char)*ptr)) return 0; val = val*10 + *ptr - '0'; } if (*ptr != ' ') return 0; ptr++; return 1;}// True will be returned for an empty line.Boolean HttpSocketStorageObject::readLine(Messenger &mgr, String<char> &line, String<char> &leftOver){ line.resize(0); Boolean hadCr = 0; Boolean gotLine = 0; size_t li; for (li = 0; li < leftOver.size(); li++) { if (leftOver[li] == '\r') { if (hadCr) { gotLine = 1; break; } line += '\r'; hadCr = 1; } else if (leftOver[li] == '\n') { line += '\n'; li++; gotLine = 1; break; } else if (hadCr) { gotLine = 1; break; } else line += leftOver[li]; } if (gotLine) { for (size_t i = li; i < leftOver.size(); i++) leftOver[i - li] = leftOver[i]; leftOver.resize(leftOver.size() - li); return 1; } leftOver.resize(0); if (eof_) return 1; for (;;) { char c; long n; do { n = readsocket(fd_, &c, 1); } while (n < 0 && errnosocket == SOCKET_EINTR); if (n == 0) { (void)closesocket(fd_); eof_ = 1; return 1; } if (n < 0) { ParentLocationMessenger(mgr).message(URLStorageMessages::readError, StringMessageArg(hostStr_), SocketMessageArg(errnosocket)); (void)closesocket(fd_); fd_ = INVALID_SOCKET; return 0; } switch (c) { case '\r': if (hadCr) { leftOver += c; return 1; } hadCr = 1; line += c; break; case '\n': line += c; return 1; default: if (hadCr) { leftOver += c; return 1; } line += c; break; } } return 0; // not reached}Boolean HttpSocketStorageObject::read(char *buf, size_t bufSize, Messenger &mgr, size_t &nread){ if (readSaved(buf, bufSize, nread)) return 1; if (fd_ == INVALID_SOCKET || eof_) return 0; long n; do { n = readsocket(fd_, buf, bufSize); } while (n < 0 && errnosocket == SOCKET_EINTR); if (n > 0) { nread = size_t(n); saveBytes(buf, nread); return 1; } if (n < 0) { ParentLocationMessenger(mgr).message(URLStorageMessages::readError, StringMessageArg(hostStr_), SocketMessageArg(errnosocket)); fd_ = INVALID_SOCKET; } else { eof_ = 1; if (closesocket(fd_) == SOCKET_ERROR) ParentLocationMessenger(mgr).message(URLStorageMessages::closeError, StringMessageArg(hostStr_), SocketMessageArg(errnosocket)); fd_ = INVALID_SOCKET; } return 0;}Boolean HttpSocketStorageObject::seekToStart(Messenger &){ CANNOT_HAPPEN(); return 0;}#endif /* SP_HAVE_SOCKET */#ifdef SP_NAMESPACE}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -