/*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#include "http/forward.h"
#include "HttpControlMsg.h"
#include "ipc/FdNotes.h"
-#include "SBuf.h"
+#include "sbuf/SBuf.h"
#include "servers/Server.h"
#if USE_AUTH
#include "auth/UserRequest.h"
#endif
#if USE_OPENSSL
+#include "security/Handshake.h"
#include "ssl/support.h"
#endif
-class ConnStateData;
class ClientHttpRequest;
-class clientStreamNode;
+class HttpHdrRangeSpec;
-class ConnectionDetail;
#if USE_OPENSSL
namespace Ssl
{
* processed.
*
* Performs HTTP message processing to kick off the actual HTTP request
- * handling objects (Http::StreamContext, ClientHttpRequest, HttpRequest).
+ * handling objects (Http::Stream, ClientHttpRequest, HttpRequest).
*
* Performs SSL-Bump processing for switching between HTTP and HTTPS protocols.
*
* managing, or for graceful half-close use the stopReceiving() or
* stopSending() methods.
*/
-class ConnStateData : public Server, public HttpControlMsgSink, public RegisteredRunner
+class ConnStateData : public Server, public HttpControlMsgSink, private IndependentRunner
{
public:
/* HttpControlMsgSink API */
virtual void sendControlMsg(HttpControlMsg);
+ virtual void doneWithControlMsg();
/// Traffic parsing
bool clientParseRequests();
/// Initializes and starts a peek-and-splice negotiation with the SSL client
void startPeekAndSplice();
- /// Called when the initialization of peek-and-splice negotiation finidhed
- void startPeekAndSpliceDone();
+
/// Called when a peek-and-splice step finished. For example after
/// server SSL certificates received and fake server SSL certificates
/// generated
void httpsPeeked(Comm::ConnectionPointer serverConnection);
/// Splice a bumped client connection on peek-and-splice mode
- void splice();
-
- /// Check on_unsupported_protocol access list and splice if required
- /// \retval true on splice
- /// \retval false otherwise
- bool spliceOnError(const err_type err);
+ bool splice();
- /// Start to create dynamic Security::ContextPtr for host or uses static port SSL context.
+ /// Start to create dynamic Security::ContextPointer for host or uses static port SSL context.
void getSslContextStart();
/**
* Done create dynamic ssl certificate.
*
* \param[in] isNew if generated certificate is new, so we need to add this certificate to storage.
*/
- void getSslContextDone(Security::ContextPtr sslContext, bool isNew = false);
+ void getSslContextDone(Security::ContextPointer &, bool isNew = false);
/// Callback function. It is called when squid receive message from ssl_crtd.
static void sslCrtdHandleReplyWrapper(void *data, const Helper::Reply &reply);
/// Proccess response from ssl_crtd.
void sslCrtdHandleReply(const Helper::Reply &reply);
void switchToHttps(HttpRequest *request, Ssl::BumpMode bumpServerMode);
+ void parseTlsHandshake();
bool switchedToHttps() const { return switchedToHttps_; }
Ssl::ServerBump *serverBump() {return sslServerBump;}
inline void setServerBump(Ssl::ServerBump *srvBump) {
/// Returns false if no [delayed] error should be written to the client.
/// Otherwise, writes the error to the client and returns true. Also checks
/// for SQUID_X509_V_ERR_DOMAIN_MISMATCH on bumped requests.
- bool serveDelayedError(Http::StreamContext *);
+ bool serveDelayedError(Http::Stream *);
Ssl::BumpMode sslBumpMode; ///< ssl_bump decision (Ssl::bumpEnd if n/a).
+ /// Tls parser to use for client HELLO messages parsing on bumped
+ /// connections.
+ Security::HandshakeParser tlsParser;
#else
bool switchedToHttps() const { return false; }
#endif
void connectionTag(const char *aTag) { connectionTag_ = aTag; }
/// handle a control message received by context from a peer and call back
- virtual void writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call) = 0;
+ virtual bool writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call) = 0;
/// ClientStream calls this to supply response header (once) and data
- /// for the current Http::StreamContext.
+ /// for the current Http::Stream.
virtual void handleReply(HttpReply *header, StoreIOBuffer receivedData) = 0;
/// remove no longer needed leading bytes from the input buffer
/* TODO: Make the methods below (at least) non-public when possible. */
/// stop parsing the request and create context for relaying error info
- Http::StreamContext *abortRequestParsing(const char *const errUri);
+ Http::Stream *abortRequestParsing(const char *const errUri);
/// generate a fake CONNECT request with the given payload
/// at the beginning of the client I/O buffer
- void fakeAConnectRequest(const char *reason, const SBuf &payload);
+ bool fakeAConnectRequest(const char *reason, const SBuf &payload);
+
+ /// generates and sends to tunnel.cc a fake request with a given payload
+ bool initiateTunneledRequest(HttpRequest::Pointer const &cause, Http::MethodType const method, const char *reason, const SBuf &payload);
+
+ /// whether tunneling of unsupported protocol is allowed for this connection
+ bool mayTunnelUnsupportedProto();
+
+ /// build a fake http request
+ ClientHttpRequest *buildFakeRequest(Http::MethodType const method, SBuf &useHost, unsigned short usePort, const SBuf &payload);
/// client data which may need to forward as-is to server after an
/// on_unsupported_protocol tunnel decision.
/// parse input buffer prefix into a single transfer protocol request
/// return NULL to request more header bytes (after checking any limits)
/// use abortRequestParsing() to handle parsing errors w/o creating request
- virtual Http::StreamContext *parseOneRequest() = 0;
+ virtual Http::Stream *parseOneRequest() = 0;
/// start processing a freshly parsed request
- virtual void processParsedRequest(Http::StreamContext *) = 0;
+ virtual void processParsedRequest(Http::StreamPointer &) = 0;
/// returning N allows a pipeline of 1+N requests (see pipeline_prefetch)
virtual int pipelinePrefetchMax() const;
private:
/* ::Server API */
virtual bool connFinishedWithConn(int size);
+ virtual void checkLogging();
void clientAfterReadingRequests();
bool concurrentRequestQueueFilled() const;
#if USE_OPENSSL
bool switchedToHttps_;
+ bool parsingTlsHandshake; ///< whether we are getting/parsing TLS Hello bytes
+
/// The SSL server host name appears in CONNECT request or the server ip address for the intercepted requests
String sslConnectHostOrIp; ///< The SSL server host name as passed in the CONNECT request
SBuf sslCommonName_; ///< CN name for SSL certificate generation
/// decide whether to expect multiple requests on the corresponding connection
void clientSetKeepaliveFlag(ClientHttpRequest *http);
+/// append a "part" HTTP header (as in a multi-part/range reply) to the buffer
+void clientPackRangeHdr(const HttpReply *, const HttpHdrRangeSpec *, String boundary, MemBuf *);
+
+/// put terminating boundary for multiparts to the buffer
+void clientPackTermBound(String boundary, MemBuf *);
+
/* misplaced declaratrions of Stream callbacks provided/used by client side */
SQUIDCEXTERN CSR clientGetMoreData;
SQUIDCEXTERN CSS clientReplyStatus;
CSD clientSocketDetach;
/* TODO: Move to HttpServer. Warning: Move requires large code nonchanges! */
-Http::StreamContext *parseHttpRequest(ConnStateData *, const Http1::RequestParserPointer &);
-void clientProcessRequest(ConnStateData *, const Http1::RequestParserPointer &, Http::StreamContext *);
+Http::Stream *parseHttpRequest(ConnStateData *, const Http1::RequestParserPointer &);
+void clientProcessRequest(ConnStateData *, const Http1::RequestParserPointer &, Http::Stream *);
void clientPostHttpsAccept(ConnStateData *);
#endif /* SQUID_CLIENTSIDE_H */