std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request) { delete _pResponseStream; _pResponseStream = 0; bool keepAlive = getKeepAlive(); if ((connected() && !keepAlive) || mustReconnect()) { close(); _mustReconnect = false; } try { if (!connected()) reconnect(); if (!keepAlive) request.setKeepAlive(false); if (!request.has(HTTPRequest::HOST)) request.setHost(_host, _port); if (!_proxyHost.empty()) { request.setURI(proxyRequestPrefix() + request.getURI()); proxyAuthenticate(request); } _reconnect = keepAlive; _expectResponseBody = request.getMethod() != HTTPRequest::HTTP_HEAD; if (request.getChunkedTransferEncoding()) { HTTPHeaderOutputStream hos(*this); request.write(hos); _pRequestStream = new HTTPChunkedOutputStream(*this); } else if (request.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH) { Poco::CountingOutputStream cs; request.write(cs); _pRequestStream = new HTTPFixedLengthOutputStream(*this, request.getContentLength() + cs.chars()); request.write(*_pRequestStream); } else if (request.getMethod() != HTTPRequest::HTTP_PUT && request.getMethod() != HTTPRequest::HTTP_POST) { Poco::CountingOutputStream cs; request.write(cs); _pRequestStream = new HTTPFixedLengthOutputStream(*this, cs.chars()); request.write(*_pRequestStream); } else { _pRequestStream = new HTTPOutputStream(*this); request.write(*_pRequestStream); } _lastRequest.update(); return *_pRequestStream; } catch (Exception&) { close(); throw; } }
std::ostream& HTTPClientSession::sendRequest(HTTPRequest& request) { clearException(); _pResponseStream = 0; bool keepAlive = getKeepAlive(); // 检查是否需要重新建立链接 if ((connected() && !keepAlive) || mustReconnect()) { close(); _mustReconnect = false; } try { if (!connected()) reconnect(); if (!keepAlive) request.setKeepAlive(false); if (!request.has(HTTPRequest::HOST)) request.setHost(_host, _port); _reconnect = keepAlive; _expectResponseBody = request.getMethod() != HTTPRequest::HTTP_HEAD; if (request.getChunkedTransferEncoding()) { throw NotImplementedException("HTTPClientSession::sendRequest can't process Chunked"); } else if (request.hasContentLength()) { CountingOutputStream cs; request.write(cs); _pRequestStream.reset(new HTTPFixedLengthOutputStream(*this, request.getContentLength() + cs.chars())); request.write(*_pRequestStream); } else if ((request.getMethod() != HTTPRequest::HTTP_PUT && request.getMethod() != HTTPRequest::HTTP_POST) || request.has(HTTPRequest::UPGRADE)) { throw NotImplementedException("HTTPClientSession::sendRequest can't process hasUpGrade"); } else { throw NotImplementedException("HTTPClientSession::sendRequest can't process Normal"); } _lastRequest.update(); return *_pRequestStream; } catch (Exception&) { close(); throw; } }
bool HTTPServerSession::hasMoreRequests() { if (!socket().impl()->initialized()) return false; if (_firstRequest) { _firstRequest = false; --_maxKeepAliveRequests; return socket().poll(getTimeout(), Socket::SELECT_READ); } else if (_maxKeepAliveRequests != 0 && getKeepAlive()) { if (_maxKeepAliveRequests > 0) --_maxKeepAliveRequests; return buffered() > 0 || socket().poll(_keepAliveTimeout, Socket::SELECT_READ); } else return false; }
std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response) { delete _pRequestStream; _pRequestStream = 0; do { response.clear(); HTTPHeaderInputStream his(*this); try { response.read(his); } catch (MessageException&) { close(); if (networkException()) networkException()->rethrow(); else throw; } catch (Exception&) { close(); throw; } } while (response.getStatus() == HTTPResponse::HTTP_CONTINUE); _mustReconnect = getKeepAlive() && !response.getKeepAlive(); if (!_expectResponseBody) _pResponseStream = new HTTPFixedLengthInputStream(*this, 0); else if (response.getChunkedTransferEncoding()) _pResponseStream = new HTTPChunkedInputStream(*this); else if (response.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH) _pResponseStream = new HTTPFixedLengthInputStream(*this, response.getContentLength()); else _pResponseStream = new HTTPInputStream(*this); return *_pResponseStream; }
std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response) { _pRequestStream = 0; if (networkException()) networkException()->rethrow(); do { response.clear(); HTTPHeaderInputStream his(*this); try { response.read(his); } catch (MessageException&) { close(); if (networkException()) networkException()->rethrow(); else throw; } catch (Exception&) { close(); throw; } } while (false /* response.getStatus() == HTTPResponse::HTTP_CONTINUE */); _mustReconnect = getKeepAlive() && !response.getKeepAlive(); if (!_expectResponseBody || response.getStatus() < 200 || response.getStatus() == HTTPResponse::HTTP_NO_CONTENT || response.getStatus() == HTTPResponse::HTTP_NOT_MODIFIED) _pResponseStream.reset(new HTTPFixedLengthInputStream(*this, 0)); else if (response.getChunkedTransferEncoding()) throw NotImplementedException("HTTPClientSession::receiveResponse ChunkedInputStream"); else if (response.hasContentLength()) _pResponseStream.reset(new HTTPFixedLengthInputStream(*this, response.getContentLength())); else throw NotImplementedException("HTTPClientSession::receiveResponse HTTPIOStream"); return *_pResponseStream; }
void handleRequest(void* ptr){ struct targs* args = ptr; int sock, copied; time_t seconds; char buf[4096]; char packets[10][4096]; char packet[8192]; int packetIndex; strcpy(packet, ""); sock = args -> newSock; //read in data recv(sock, buf, sizeof(buf), 0); int x; strcat(packet, buf); for(x=0;x<4096;x++)buf[x] = 0; int keepalive = 1; do{ packetIndex = -1; //read whatever is on the socket fully while(copied = recv(sock, buf, sizeof(buf), MSG_DONTWAIT) > 0){ int i; strcat(packet, buf); for(i=0;i<4096;i++)buf[i] = 0; } //extract data from packet if(strlen(packet) > 0){ char packetsCop[8192]; strcpy(packetsCop, packet); //split the received data into packets char* token = strtok(packetsCop, "\n"); while(token != NULL){ int e = strlen(token); if(strstr(token, "HTTP/") != NULL){ packetIndex += 1; strcpy( packets[packetIndex], ""); } strcat(packets[packetIndex], token); strcat(packets[packetIndex], "\n"); token = strtok(NULL, "\n"); } int t; //iterate throught each packet and process appropriately for(t = 0; t <= packetIndex; t++){ //update our timeout seconds = time(NULL); char method[2048]; char http[512]; //check if the method is ok if(methodOk(packets[t], method) < 0){ sendBad(sock, method, 0); //send 400: invalid method keepalive = 0; } //check if the http version is ok else if(httpOk(packets[t], http) < 0){ sendBad(sock, http, 2); //send 400: invalid http version keepalive = 0; } else{ //check whether or not we want to keep the connection open getKeepAlive(packets[t], (int*)&keepalive); char fileName[4096]; int status; //get the file name from the packet and do additional processing status = getFileName(packets[t], fileName); //determine what to do with packet if(status == 200){ sendFile(sock, fileName, keepalive); } else if(status == 404){ sendNotFound(sock, fileName); keepalive = 0; } else if(status == 400){ sendBad(sock, fileName, 1); keepalive = 0; } else if(status == 501){ sendBad(sock, fileName, 3); keepalive = 0; } } } int r; for(r=0;r<packetIndex;r++)packets[r][0] = 0; } int i; for(i=0;i<sizeof(packet);i++)packet[i] = 0; strcpy(packet, ""); }while(keepalive && ((time(NULL)) - (seconds) < 10)); close(sock); free(args); pthread_exit((void*)(0)); }