Very rough first start, not even everything added
This commit is contained in:
commit
af3619d4fa
88 changed files with 24251 additions and 0 deletions
313
HTTPUtilitiesLib/HTTPProtocol.cpp
Normal file
313
HTTPUtilitiesLib/HTTPProtocol.cpp
Normal file
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
#include "HTTPProtocol.h"
|
||||
|
||||
StrPtrLen HTTPProtocol::sMethods[] =
|
||||
{
|
||||
StrPtrLen("GET"),
|
||||
StrPtrLen("HEAD"),
|
||||
StrPtrLen("POST"),
|
||||
StrPtrLen("OPTIONS"),
|
||||
StrPtrLen("PUT"),
|
||||
StrPtrLen("DELETE"),
|
||||
StrPtrLen("TRACE"),
|
||||
StrPtrLen("CONNECT"),
|
||||
};
|
||||
|
||||
HTTPMethod HTTPProtocol::GetMethod(const StrPtrLen* inMethodStr)
|
||||
{
|
||||
HTTPMethod theMethod = httpIllegalMethod;
|
||||
|
||||
if (inMethodStr->Len == 0)
|
||||
return httpIllegalMethod;
|
||||
|
||||
switch((inMethodStr->Ptr)[0])
|
||||
{
|
||||
case 'G': theMethod = httpGetMethod; break;
|
||||
case 'H': theMethod = httpHeadMethod; break;
|
||||
case 'P': theMethod = httpPostMethod; break; // Most likely POST and not PUT
|
||||
case 'O': theMethod = httpOptionsMethod; break;
|
||||
case 'D': theMethod = httpDeleteMethod; break;
|
||||
case 'T': theMethod = httpTraceMethod; break;
|
||||
case 'C': theMethod = httpConnectMethod; break;
|
||||
}
|
||||
|
||||
if ( (theMethod != httpIllegalMethod) && (inMethodStr->Equal(sMethods[theMethod])) )
|
||||
return theMethod;
|
||||
|
||||
// Check for remaining methods (Only PUT method is left)
|
||||
if ( inMethodStr->Equal(sMethods[httpPutMethod]) )
|
||||
return httpPutMethod;
|
||||
|
||||
return httpIllegalMethod;
|
||||
}
|
||||
|
||||
StrPtrLen HTTPProtocol::sHeaders[] =
|
||||
{
|
||||
StrPtrLen("Connection"),
|
||||
StrPtrLen("Date"),
|
||||
StrPtrLen("Authorization"),
|
||||
StrPtrLen("If-Modified-Since"),
|
||||
StrPtrLen("Server"),
|
||||
StrPtrLen("WWW-Authenticate"),
|
||||
StrPtrLen("Expires"),
|
||||
StrPtrLen("Last-Modified"),
|
||||
|
||||
StrPtrLen("Cache-Control"),
|
||||
StrPtrLen("Pragma"),
|
||||
StrPtrLen("Trailer"),
|
||||
StrPtrLen("Transfer-Encoding"),
|
||||
StrPtrLen("Upgrade"),
|
||||
StrPtrLen("Via"),
|
||||
StrPtrLen("Warning"),
|
||||
|
||||
StrPtrLen("Accept"),
|
||||
StrPtrLen("Accept-Charset"),
|
||||
StrPtrLen("Accept-Encoding"),
|
||||
StrPtrLen("Accept-Language"),
|
||||
StrPtrLen("Expect"),
|
||||
StrPtrLen("From"),
|
||||
StrPtrLen("Host"),
|
||||
StrPtrLen("If-Match"),
|
||||
StrPtrLen("If-None-Match"),
|
||||
StrPtrLen("If-Range"),
|
||||
StrPtrLen("If-Unmodified-Since"),
|
||||
StrPtrLen("Max-Forwards"),
|
||||
StrPtrLen("Proxy-Authorization"),
|
||||
StrPtrLen("Range"),
|
||||
StrPtrLen("Referer"),
|
||||
StrPtrLen("TE"),
|
||||
StrPtrLen("User-Agent"),
|
||||
|
||||
StrPtrLen("Accept-Ranges"),
|
||||
StrPtrLen("Age"),
|
||||
StrPtrLen("ETag"),
|
||||
StrPtrLen("Location"),
|
||||
StrPtrLen("Proxy-Authenticate"),
|
||||
StrPtrLen("Retry-After"),
|
||||
StrPtrLen("Vary"),
|
||||
|
||||
StrPtrLen("Allow"),
|
||||
StrPtrLen("Content-Encoding"),
|
||||
StrPtrLen("Content-Language"),
|
||||
StrPtrLen("Content-Length"),
|
||||
StrPtrLen("Content-Location"),
|
||||
StrPtrLen("Content-MD5"),
|
||||
StrPtrLen("Content-Range"),
|
||||
StrPtrLen("Content-Type"),
|
||||
|
||||
StrPtrLen("X-SessionCookie"),
|
||||
StrPtrLen("X-Server-IP-Address"),
|
||||
|
||||
StrPtrLen(" ,")
|
||||
};
|
||||
|
||||
HTTPHeader HTTPProtocol::GetHeader(const StrPtrLen* inHeaderStr)
|
||||
{
|
||||
if (inHeaderStr->Len == 0)
|
||||
return httpIllegalHeader;
|
||||
|
||||
HTTPHeader theHeader = httpIllegalHeader;
|
||||
|
||||
//chances are this is one of our selected "VIP" headers. so check for this.
|
||||
switch((inHeaderStr->Ptr)[0])
|
||||
{
|
||||
case 'C': case 'c': theHeader = httpConnectionHeader; break;
|
||||
case 'S': case 's': theHeader = httpServerHeader; break;
|
||||
case 'D': case 'd': theHeader = httpDateHeader; break;
|
||||
case 'A': case 'a': theHeader = httpAuthorizationHeader; break;
|
||||
case 'W': case 'w': theHeader = httpWWWAuthenticateHeader; break;
|
||||
case 'I': case 'i': theHeader = httpIfModifiedSinceHeader; break;
|
||||
case 'E': case 'e': theHeader = httpExpiresHeader; break;
|
||||
case 'L': case 'l': theHeader = httpLastModifiedHeader; break;
|
||||
// Added this to optimize for HTTP tunnelling in the server (Not really a VIP header)
|
||||
case 'X': case 'x': theHeader = httpSessionCookieHeader; break;
|
||||
}
|
||||
|
||||
if ((theHeader != httpIllegalHeader) &&
|
||||
(inHeaderStr->EqualIgnoreCase(sHeaders[theHeader].Ptr, sHeaders[theHeader].Len)))
|
||||
return theHeader;
|
||||
|
||||
//If this isn't one of our VIP headers, go through the remaining request headers, trying
|
||||
//to find the right one.
|
||||
for (SInt32 x = httpNumVIPHeaders; x < httpNumHeaders; x++)
|
||||
if (inHeaderStr->EqualIgnoreCase(sHeaders[x].Ptr, sHeaders[x].Len))
|
||||
return x;
|
||||
return httpIllegalHeader;
|
||||
}
|
||||
|
||||
StrPtrLen HTTPProtocol::sStatusCodeStrings[] =
|
||||
{
|
||||
StrPtrLen("Continue"), //kContinue
|
||||
StrPtrLen("Switching Protocols"), //kSwitchingProtocols
|
||||
StrPtrLen("OK"), //kOK
|
||||
StrPtrLen("Created"), //kCreated
|
||||
StrPtrLen("Accepted"), //kAccepted
|
||||
StrPtrLen("Non Authoritative Information"), //kNonAuthoritativeInformation
|
||||
StrPtrLen("No Content"), //kNoContent
|
||||
StrPtrLen("Reset Content"), //kResetContent
|
||||
StrPtrLen("Partial Content"), //kPartialContent
|
||||
StrPtrLen("Multiple Choices"), //kMultipleChoices
|
||||
StrPtrLen("Moved Permanently"), //kMovedPermanently
|
||||
StrPtrLen("Found"), //kFound
|
||||
StrPtrLen("See Other"), //kSeeOther
|
||||
StrPtrLen("Not Modified"), //kNotModified
|
||||
StrPtrLen("Use Proxy"), //kUseProxy
|
||||
StrPtrLen("Temporary Redirect"), //kTemporaryRedirect
|
||||
StrPtrLen("Bad Request"), //kBadRequest
|
||||
StrPtrLen("Unauthorized"), //kUnAuthorized
|
||||
StrPtrLen("Payment Required"), //kPaymentRequired
|
||||
StrPtrLen("Forbidden"), //kForbidden
|
||||
StrPtrLen("Not Found"), //kNotFound
|
||||
StrPtrLen("Method Not Allowed"), //kMethodNotAllowed
|
||||
StrPtrLen("Not Acceptable"), //kNotAcceptable
|
||||
StrPtrLen("Proxy Authentication Required"), //kProxyAuthenticationRequired
|
||||
StrPtrLen("Request Time-out"), //kRequestTimeout
|
||||
StrPtrLen("Conflict"), //kConflict
|
||||
StrPtrLen("Gone"), //kGone
|
||||
StrPtrLen("Length Required"), //kLengthRequired
|
||||
StrPtrLen("Precondition Failed"), //kPreconditionFailed
|
||||
StrPtrLen("Request Entity Too Large"), //kRequestEntityTooLarge
|
||||
StrPtrLen("Request-URI Too Large"), //kRequestURITooLarge
|
||||
StrPtrLen("Unsupported Media Type"), //kUnsupportedMediaType
|
||||
StrPtrLen("Request Range Not Satisfiable"), //kRequestRangeNotSatisfiable
|
||||
StrPtrLen("Expectation Failed"), //kExpectationFailed
|
||||
StrPtrLen("Internal Server Error"), //kInternalServerError
|
||||
StrPtrLen("Not Implemented"), //kNotImplemented
|
||||
StrPtrLen("Bad Gateway"), //kBadGateway
|
||||
StrPtrLen("Service Unavailable"), //kServiceUnavailable
|
||||
StrPtrLen("Gateway Timeout"), //kGatewayTimeout
|
||||
StrPtrLen("HTTP Version not supported") //kHTTPVersionNotSupported
|
||||
};
|
||||
|
||||
SInt32 HTTPProtocol::sStatusCodes[] =
|
||||
{
|
||||
100, //kContinue
|
||||
101, //kSwitchingProtocols
|
||||
200, //kOK
|
||||
201, //kCreated
|
||||
202, //kAccepted
|
||||
203, //kNonAuthoritativeInformation
|
||||
204, //kNoContent
|
||||
205, //kResetContent
|
||||
206, //kPartialContent
|
||||
300, //kMultipleChoices
|
||||
301, //kMovedPermanently
|
||||
302, //kFound
|
||||
303, //kSeeOther
|
||||
304, //kNotModified
|
||||
305, //kUseProxy
|
||||
307, //kTemporaryRedirect
|
||||
400, //kBadRequest
|
||||
401, //kUnAuthorized
|
||||
402, //kPaymentRequired
|
||||
403, //kForbidden
|
||||
404, //kNotFound
|
||||
405, //kMethodNotAllowed
|
||||
406, //kNotAcceptable
|
||||
407, //kProxyAuthenticationRequired
|
||||
408, //kRequestTimeout
|
||||
409, //kConflict
|
||||
410, //kGone
|
||||
411, //kLengthRequired
|
||||
412, //kPreconditionFailed
|
||||
413, //kRequestEntityTooLarge
|
||||
414, //kRequestURITooLarge
|
||||
415, //kUnsupportedMediaType
|
||||
416, //kRequestRangeNotSatisfiable
|
||||
417, //kExpectationFailed
|
||||
500, //kInternalServerError
|
||||
501, //kNotImplemented
|
||||
502, //kBadGateway
|
||||
503, //kServiceUnavailable
|
||||
504, //kGatewayTimeout
|
||||
505 //kHTTPVersionNotSupported
|
||||
};
|
||||
|
||||
StrPtrLen HTTPProtocol::sStatusCodeAsStrings[] =
|
||||
{
|
||||
StrPtrLen("100"), //kContinue
|
||||
StrPtrLen("101"), //kSwitchingProtocols
|
||||
StrPtrLen("200"), //kOK
|
||||
StrPtrLen("201"), //kCreated
|
||||
StrPtrLen("202"), //kAccepted
|
||||
StrPtrLen("203"), //kNonAuthoritativeInformation
|
||||
StrPtrLen("204"), //kNoContent
|
||||
StrPtrLen("205"), //kResetContent
|
||||
StrPtrLen("206"), //kPartialContent
|
||||
StrPtrLen("300"), //kMultipleChoices
|
||||
StrPtrLen("301"), //kMovedPermanently
|
||||
StrPtrLen("302"), //kFound
|
||||
StrPtrLen("303"), //kSeeOther
|
||||
StrPtrLen("304"), //kNotModified
|
||||
StrPtrLen("305"), //kUseProxy
|
||||
StrPtrLen("307"), //kTemporaryRedirect
|
||||
StrPtrLen("400"), //kBadRequest
|
||||
StrPtrLen("401"), //kUnAuthorized
|
||||
StrPtrLen("402"), //kPaymentRequired
|
||||
StrPtrLen("403"), //kForbidden
|
||||
StrPtrLen("404"), //kNotFound
|
||||
StrPtrLen("405"), //kMethodNotAllowed
|
||||
StrPtrLen("406"), //kNotAcceptable
|
||||
StrPtrLen("407"), //kProxyAuthenticationRequired
|
||||
StrPtrLen("408"), //kRequestTimeout
|
||||
StrPtrLen("409"), //kConflict
|
||||
StrPtrLen("410"), //kGone
|
||||
StrPtrLen("411"), //kLengthRequired
|
||||
StrPtrLen("412"), //kPreconditionFailed
|
||||
StrPtrLen("413"), //kRequestEntityTooLarge
|
||||
StrPtrLen("414"), //kRequestURITooLarge
|
||||
StrPtrLen("415"), //kUnsupportedMediaType
|
||||
StrPtrLen("416"), //kRequestRangeNotSatisfiable
|
||||
StrPtrLen("417"), //kExpectationFailed
|
||||
StrPtrLen("500"), //kInternalServerError
|
||||
StrPtrLen("501"), //kNotImplemented
|
||||
StrPtrLen("502"), //kBadGateway
|
||||
StrPtrLen("503"), //kServiceUnavailable
|
||||
StrPtrLen("504"), //kGatewayTimeout
|
||||
StrPtrLen("505") //kHTTPVersionNotSupported
|
||||
};
|
||||
|
||||
StrPtrLen HTTPProtocol::sVersionStrings[] =
|
||||
{
|
||||
StrPtrLen("HTTP/0.9"),
|
||||
StrPtrLen("HTTP/1.0"),
|
||||
StrPtrLen("HTTP/1.1")
|
||||
};
|
||||
|
||||
HTTPVersion HTTPProtocol::GetVersion(StrPtrLen* versionStr)
|
||||
{
|
||||
if (versionStr->Len != 8)
|
||||
return httpIllegalVersion;
|
||||
SInt32 limit = httpNumVersions;
|
||||
for (SInt32 x = 0; x < limit; x++)
|
||||
{
|
||||
if (versionStr->EqualIgnoreCase(sVersionStrings[x].Ptr, sVersionStrings[x].Len))
|
||||
return x;
|
||||
}
|
||||
|
||||
return httpIllegalVersion;
|
||||
}
|
||||
|
204
HTTPUtilitiesLib/HTTPProtocol.h
Normal file
204
HTTPUtilitiesLib/HTTPProtocol.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
#ifndef __HTTPPROTOCOL_H__
|
||||
#define __HTTPPROTOCOL_H__
|
||||
|
||||
#include "OSHeaders.h"
|
||||
#include "StrPtrLen.h"
|
||||
|
||||
// Versions
|
||||
enum
|
||||
{
|
||||
http09version = 0,
|
||||
http10Version = 1,
|
||||
http11Version = 2,
|
||||
|
||||
httpNumVersions = 3,
|
||||
httpIllegalVersion = 3
|
||||
};
|
||||
typedef UInt32 HTTPVersion;
|
||||
|
||||
// Methods
|
||||
enum
|
||||
{
|
||||
httpGetMethod = 0,
|
||||
httpHeadMethod = 1,
|
||||
httpPostMethod = 2,
|
||||
httpOptionsMethod = 3,
|
||||
httpPutMethod = 4,
|
||||
httpDeleteMethod = 5,
|
||||
httpTraceMethod = 6,
|
||||
httpConnectMethod = 7,
|
||||
|
||||
httpNumMethods = 8,
|
||||
httpIllegalMethod = 8
|
||||
};
|
||||
typedef UInt32 HTTPMethod;
|
||||
|
||||
// Headers
|
||||
enum
|
||||
{
|
||||
// VIP headers
|
||||
httpConnectionHeader = 0, // general header
|
||||
httpDateHeader = 1, // general header
|
||||
httpAuthorizationHeader = 2, // request header
|
||||
httpIfModifiedSinceHeader = 3, // request header
|
||||
httpServerHeader = 4, // response header
|
||||
httpWWWAuthenticateHeader = 5, // response header
|
||||
httpExpiresHeader = 6, // entity header
|
||||
httpLastModifiedHeader = 7, // entity header
|
||||
httpNumVIPHeaders = 8,
|
||||
|
||||
//Other general http headers
|
||||
httpCacheControlHeader = 8,
|
||||
httpPragmaHeader = 9,
|
||||
httpTrailerHeader = 10,
|
||||
httpTransferEncodingHeader = 11,
|
||||
httpUpgradeHeader = 12,
|
||||
httpViaHeader = 13,
|
||||
httpWarningHeader = 14,
|
||||
|
||||
// Other request headers
|
||||
httpAcceptHeader = 15,
|
||||
httpAcceptCharsetHeader = 16,
|
||||
httpAcceptEncodingHeader = 17,
|
||||
httpAcceptLanguageHeader = 18,
|
||||
httpExpectHeader = 19,
|
||||
httpFromHeader = 20,
|
||||
httpHostHeader = 21,
|
||||
httpIfMatchHeader = 22,
|
||||
httpIfNoneMatchHeader = 23,
|
||||
httpIfRangeHeader = 24,
|
||||
httpIfUnmodifiedSinceHeader = 25,
|
||||
httpMaxForwardsHeader = 26,
|
||||
httpProxyAuthorizationHeader = 27,
|
||||
httpRangeHeader = 28,
|
||||
httpRefererHeader = 29,
|
||||
httpTEHeader = 30,
|
||||
httpUserAgentHeader = 31,
|
||||
|
||||
// Other response headers
|
||||
httpAcceptRangesHeader = 32,
|
||||
httpAgeHeader = 33,
|
||||
httpETagHeader = 34,
|
||||
httpLocationHeader = 35,
|
||||
httpProxyAuthenticateHeader = 36,
|
||||
httpRetryAfterHeader = 37,
|
||||
httpVaryHeader = 38,
|
||||
|
||||
// Other entity headers
|
||||
httpAllowHeader = 39,
|
||||
httpContentEncodingHeader = 40,
|
||||
httpContentLanguageHeader = 41,
|
||||
httpContentLengthHeader = 42,
|
||||
httpContentLocationHeader = 43,
|
||||
httpContentMD5Header = 44,
|
||||
httpContentRangeHeader = 45,
|
||||
httpContentTypeHeader = 46,
|
||||
|
||||
// QTSS Specific headers
|
||||
// Add headers that are not part of the HTTP spec here
|
||||
// Make sure and up the number of headers and httpIllegalHeader number
|
||||
httpSessionCookieHeader = 47, // Used for HTTP tunnelling
|
||||
httpServerIPAddressHeader = 48,
|
||||
|
||||
httpNumHeaders = 49,
|
||||
httpIllegalHeader = 49
|
||||
};
|
||||
typedef UInt32 HTTPHeader;
|
||||
|
||||
// Status codes
|
||||
enum
|
||||
{
|
||||
httpContinue = 0, //100
|
||||
httpSwitchingProtocols = 1, //101
|
||||
httpOK = 2, //200
|
||||
httpCreated = 3, //201
|
||||
httpAccepted = 4, //202
|
||||
httpNonAuthoritativeInformation = 5, //203
|
||||
httpNoContent = 6, //204
|
||||
httpResetContent = 7, //205
|
||||
httpPartialContent = 8, //206
|
||||
httpMultipleChoices = 9, //300
|
||||
httpMovedPermanently = 10, //301
|
||||
httpFound = 11, //302
|
||||
httpSeeOther = 12, //303
|
||||
httpNotModified = 13, //304
|
||||
httpUseProxy = 14, //305
|
||||
httpTemporaryRedirect = 15, //307
|
||||
httpBadRequest = 16, //400
|
||||
httpUnAuthorized = 17, //401
|
||||
httpPaymentRequired = 18, //402
|
||||
httpForbidden = 19, //403
|
||||
httpNotFound = 20, //404
|
||||
httpMethodNotAllowed = 21, //405
|
||||
httpNotAcceptable = 22, //406
|
||||
httpProxyAuthenticationRequired = 23, //407
|
||||
httpRequestTimeout = 24, //408
|
||||
httpConflict = 25, //409
|
||||
httpGone = 26, //410
|
||||
httpLengthRequired = 27, //411
|
||||
httpPreconditionFailed = 28, //412
|
||||
httpRequestEntityTooLarge = 29, //413
|
||||
httpRequestURITooLarge = 30, //414
|
||||
httpUnsupportedMediaType = 31, //415
|
||||
httpRequestRangeNotSatisfiable = 32, //416
|
||||
httpExpectationFailed = 33, //417
|
||||
httpInternalServerError = 34, //500
|
||||
httpNotImplemented = 35, //501
|
||||
httpBadGateway = 36, //502
|
||||
httpServiceUnavailable = 37, //503
|
||||
httpGatewayTimeout = 38, //504
|
||||
httpHTTPVersionNotSupported = 39, //505
|
||||
httpNumStatusCodes = 40
|
||||
};
|
||||
typedef UInt32 HTTPStatusCode;
|
||||
|
||||
class HTTPProtocol
|
||||
{
|
||||
public:
|
||||
// Methods
|
||||
static HTTPMethod GetMethod(const StrPtrLen* inMethodStr);
|
||||
static StrPtrLen* GetMethodString(HTTPMethod inMethod) { return &sMethods[inMethod]; }
|
||||
// Headers
|
||||
static HTTPHeader GetHeader(const StrPtrLen* inHeaderStr);
|
||||
static StrPtrLen* GetHeaderString(HTTPHeader inHeader) { return &sHeaders[inHeader]; }
|
||||
// Status codes
|
||||
static StrPtrLen* GetStatusCodeString(HTTPStatusCode inStat) { return &sStatusCodeStrings[inStat]; }
|
||||
static SInt32 GetStatusCode(HTTPStatusCode inStat) { return sStatusCodes[inStat]; }
|
||||
static StrPtrLen* GetStatusCodeAsString(HTTPStatusCode inStat) { return &sStatusCodeAsStrings[inStat]; }
|
||||
// Versions
|
||||
static HTTPVersion GetVersion(StrPtrLen* versionStr);
|
||||
static StrPtrLen* GetVersionString(HTTPVersion version) { return &sVersionStrings[version]; }
|
||||
|
||||
private:
|
||||
static StrPtrLen sMethods[];
|
||||
static StrPtrLen sHeaders[];
|
||||
static StrPtrLen sStatusCodeStrings[];
|
||||
static StrPtrLen sStatusCodeAsStrings[];
|
||||
static SInt32 sStatusCodes[];
|
||||
static StrPtrLen sVersionStrings[];
|
||||
};
|
||||
#endif // __HTTPPROTOCOL_H__
|
419
HTTPUtilitiesLib/HTTPRequest.cpp
Normal file
419
HTTPUtilitiesLib/HTTPRequest.cpp
Normal file
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
#include "HTTPRequest.h"
|
||||
#include "HTTPProtocol.h"
|
||||
#include "OSMemory.h"
|
||||
#include "StringParser.h"
|
||||
#include "StringTranslator.h"
|
||||
#include "ResizeableStringFormatter.h"
|
||||
#include "DateTranslator.h"
|
||||
|
||||
|
||||
StrPtrLen HTTPRequest::sColonSpace(": ", 2);
|
||||
static Bool16 sFalse = false;
|
||||
static Bool16 sTrue = true;
|
||||
static StrPtrLen sCloseString("close", 5);
|
||||
static StrPtrLen sKeepAliveString("keep-alive", 10);
|
||||
static StrPtrLen sDefaultRealm("Streaming Server", 19);
|
||||
UInt8 HTTPRequest::sURLStopConditions[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, //0-9 //'\t' is a stop condition
|
||||
1, 0, 0, 1, 0, 0, 0, 0, 0, 0, //10-19 //'\r' & '\n' are stop conditions
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-29
|
||||
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, //30-39 //' '
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-49
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-59
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //60-69
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //90-99
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //120-129
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170-179
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180-189
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190-199
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200-209
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210-219
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220-229
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230-239
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240-249
|
||||
0, 0, 0, 0, 0, 0 //250-255
|
||||
};
|
||||
|
||||
|
||||
// Constructor
|
||||
HTTPRequest::HTTPRequest(StrPtrLen* serverHeader, StrPtrLen* requestPtr)
|
||||
{
|
||||
// Store the pointer to the server header field
|
||||
fSvrHeader = *serverHeader;
|
||||
|
||||
// Set initial state
|
||||
fRequestHeader = *requestPtr;
|
||||
fResponseHeader = NULL;
|
||||
fResponseFormatter = NULL;
|
||||
fMethod = httpIllegalMethod;
|
||||
fVersion = httpIllegalVersion;
|
||||
fAbsoluteURI = NULL;
|
||||
fRelativeURI = NULL;
|
||||
fAbsoluteURIScheme = NULL;
|
||||
fHostHeader = NULL;
|
||||
fRequestPath = NULL;
|
||||
fStatusCode = httpOK;
|
||||
fRequestKeepAlive = false; // Default value when there is no version string
|
||||
}
|
||||
|
||||
// Constructor for creating a response only
|
||||
HTTPRequest::HTTPRequest(StrPtrLen* serverHeader)
|
||||
{
|
||||
// Store the pointer to the server header field
|
||||
fSvrHeader = *serverHeader;
|
||||
|
||||
// We do not require any of these:
|
||||
fRequestHeader = NULL;
|
||||
|
||||
fMethod = httpIllegalMethod;
|
||||
fVersion = httpIllegalVersion;
|
||||
fRequestLine = NULL;
|
||||
fAbsoluteURI = NULL;
|
||||
fRelativeURI = NULL;
|
||||
fAbsoluteURIScheme = NULL;
|
||||
fHostHeader = NULL;
|
||||
fRequestPath = NULL;
|
||||
fStatusCode = 0;
|
||||
fRequestKeepAlive = false;
|
||||
|
||||
// We require the response but we allocate memory only when we call
|
||||
// CreateResponseHeader
|
||||
fResponseHeader = NULL;
|
||||
fResponseFormatter = NULL;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
HTTPRequest::~HTTPRequest()
|
||||
{
|
||||
if (fResponseHeader != NULL)
|
||||
{
|
||||
if (fResponseHeader->Ptr != NULL)
|
||||
delete fResponseHeader->Ptr;
|
||||
delete fResponseHeader;
|
||||
}
|
||||
if (fResponseFormatter != NULL)
|
||||
delete fResponseFormatter;
|
||||
if (fRequestPath != NULL)
|
||||
delete [] fRequestPath;
|
||||
}
|
||||
//Parses the request
|
||||
QTSS_Error HTTPRequest::Parse()
|
||||
{
|
||||
Assert(fRequestHeader.Ptr != NULL);
|
||||
StringParser parser(&fRequestHeader);
|
||||
|
||||
// Store the request line (used for logging)
|
||||
// (ex: GET /index.html HTTP/1.0)
|
||||
StringParser requestLineParser(&fRequestHeader);
|
||||
requestLineParser.ConsumeUntil(&fRequestLine, StringParser::sEOLMask);
|
||||
|
||||
// Parse request line returns an error if there is an error in the
|
||||
// request URI or the formatting of the request line.
|
||||
// If the method or version are not found, they are set
|
||||
// to httpIllegalMethod or httpIllegalVersion respectively,
|
||||
// and QTSS_NoErr is returned.
|
||||
QTSS_Error err = ParseRequestLine(&parser);
|
||||
if (err != QTSS_NoErr)
|
||||
return err;
|
||||
|
||||
// Parse headers and set values of headers into fFieldValues array
|
||||
err = ParseHeaders(&parser);
|
||||
if (err != QTSS_NoErr)
|
||||
return err;
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
QTSS_Error HTTPRequest::ParseRequestLine(StringParser* parser)
|
||||
{
|
||||
// Get the method - If the method is not one of the defined methods
|
||||
// then it doesn't return an error but sets fMethod to httpIllegalMethod
|
||||
StrPtrLen theParsedData;
|
||||
parser->ConsumeWord(&theParsedData);
|
||||
fMethod = HTTPProtocol::GetMethod(&theParsedData);
|
||||
|
||||
// Consume whitespace
|
||||
parser->ConsumeWhitespace();
|
||||
|
||||
// Parse the URI - If it fails returns an error after setting
|
||||
// the fStatusCode to the appropriate error code
|
||||
QTSS_Error err = ParseURI(parser);
|
||||
if (err != QTSS_NoErr)
|
||||
return err;
|
||||
|
||||
// Consume whitespace
|
||||
parser->ConsumeWhitespace();
|
||||
|
||||
// If there is a version, consume the version string
|
||||
StrPtrLen versionStr;
|
||||
parser->ConsumeUntil(&versionStr, StringParser::sEOLMask);
|
||||
// Check the version
|
||||
if (versionStr.Len > 0)
|
||||
fVersion = HTTPProtocol::GetVersion(&versionStr);
|
||||
|
||||
// Go past the end of line
|
||||
if (!parser->ExpectEOL())
|
||||
{
|
||||
fStatusCode = httpBadRequest;
|
||||
return QTSS_BadArgument; // Request line is not properly formatted!
|
||||
}
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
QTSS_Error HTTPRequest::ParseURI(StringParser* parser)
|
||||
{
|
||||
|
||||
// read in the complete URL into fRequestAbsURI
|
||||
parser->ConsumeUntil(&fAbsoluteURI, sURLStopConditions);
|
||||
|
||||
StringParser urlParser(&fAbsoluteURI);
|
||||
|
||||
// we always should have a slash before the URI
|
||||
// If not, that indicates this is a full URI
|
||||
if (fAbsoluteURI.Ptr[0] != '/')
|
||||
{
|
||||
//if it is a full URL, store the scheme and host name
|
||||
urlParser.ConsumeLength(&fAbsoluteURIScheme, 7); //consume "http://"
|
||||
urlParser.ConsumeUntil(&fHostHeader, '/');
|
||||
}
|
||||
|
||||
// whatever is in this position is the relative URI
|
||||
StrPtrLen relativeURI(urlParser.GetCurrentPosition(), urlParser.GetDataReceivedLen() - urlParser.GetDataParsedLen());
|
||||
// read this URI into fRequestRelURI
|
||||
fRelativeURI = relativeURI;
|
||||
|
||||
// Allocate memory for fRequestPath
|
||||
UInt32 len = fRelativeURI.Len;
|
||||
len++;
|
||||
char* relativeURIDecoded = NEW char[len];
|
||||
|
||||
SInt32 theBytesWritten = StringTranslator::DecodeURL(fRelativeURI.Ptr, fRelativeURI.Len,
|
||||
relativeURIDecoded, len);
|
||||
|
||||
//if negative, an error occurred, reported as an QTSS_Error
|
||||
//we also need to leave room for a terminator.
|
||||
if ((theBytesWritten < 0) || ((UInt32)theBytesWritten == len))
|
||||
{
|
||||
fStatusCode = httpBadRequest;
|
||||
return QTSS_BadArgument;
|
||||
}
|
||||
fRequestPath = NEW char[theBytesWritten + 1];
|
||||
::memcpy(fRequestPath, relativeURIDecoded + 1, theBytesWritten);
|
||||
delete relativeURIDecoded;
|
||||
fRequestPath[theBytesWritten] = '\0';
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
// Parses the Connection header and makes sure that request is properly terminated
|
||||
QTSS_Error HTTPRequest::ParseHeaders(StringParser* parser)
|
||||
{
|
||||
StrPtrLen theKeyWord;
|
||||
Bool16 isStreamOK;
|
||||
|
||||
//Repeat until we get a \r\n\r\n, which signals the end of the headers
|
||||
while ((parser->PeekFast() != '\r') && (parser->PeekFast() != '\n'))
|
||||
{
|
||||
//First get the header identifier
|
||||
|
||||
isStreamOK = parser->GetThru(&theKeyWord, ':');
|
||||
if (!isStreamOK)
|
||||
{ // No colon after header!
|
||||
fStatusCode = httpBadRequest;
|
||||
return QTSS_BadArgument;
|
||||
}
|
||||
|
||||
if (parser->PeekFast() == ' ')
|
||||
{ // handle space, if any
|
||||
isStreamOK = parser->Expect(' ');
|
||||
Assert(isStreamOK);
|
||||
}
|
||||
|
||||
//Look up the proper header enumeration based on the header string.
|
||||
HTTPHeader theHeader = HTTPProtocol::GetHeader(&theKeyWord);
|
||||
|
||||
StrPtrLen theHeaderVal;
|
||||
isStreamOK = parser->GetThruEOL(&theHeaderVal);
|
||||
|
||||
if (!isStreamOK)
|
||||
{ // No EOL after header!
|
||||
fStatusCode = httpBadRequest;
|
||||
return QTSS_BadArgument;
|
||||
}
|
||||
|
||||
// If this is the connection header
|
||||
if ( theHeader == httpConnectionHeader )
|
||||
{ // Set the keep alive boolean based on the connection header value
|
||||
SetKeepAlive(&theHeaderVal);
|
||||
}
|
||||
|
||||
// Have the header field and the value; Add value to the array
|
||||
// If the field is invalid (or unrecognized) just skip over gracefully
|
||||
if ( theHeader != httpIllegalHeader )
|
||||
fFieldValues[theHeader] = theHeaderVal;
|
||||
|
||||
}
|
||||
|
||||
isStreamOK = parser->ExpectEOL();
|
||||
Assert(isStreamOK);
|
||||
|
||||
return QTSS_NoErr;
|
||||
}
|
||||
|
||||
void HTTPRequest::SetKeepAlive(StrPtrLen *keepAliveValue)
|
||||
{
|
||||
if ( sCloseString.EqualIgnoreCase(keepAliveValue->Ptr, keepAliveValue->Len) )
|
||||
fRequestKeepAlive = sFalse;
|
||||
else
|
||||
{
|
||||
Assert( sKeepAliveString.EqualIgnoreCase(keepAliveValue->Ptr, keepAliveValue->Len) );
|
||||
fRequestKeepAlive = sTrue;
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequest::PutStatusLine(StringFormatter* putStream, HTTPStatusCode status,
|
||||
HTTPVersion version)
|
||||
{
|
||||
putStream->Put(*(HTTPProtocol::GetVersionString(version)));
|
||||
putStream->PutSpace();
|
||||
putStream->Put(*(HTTPProtocol::GetStatusCodeAsString(status)));
|
||||
putStream->PutSpace();
|
||||
putStream->Put(*(HTTPProtocol::GetStatusCodeString(status)));
|
||||
putStream->PutEOL();
|
||||
}
|
||||
|
||||
StrPtrLen* HTTPRequest::GetHeaderValue(HTTPHeader inHeader)
|
||||
{
|
||||
if ( inHeader != httpIllegalHeader )
|
||||
return &fFieldValues[inHeader];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void HTTPRequest:: CreateResponseHeader(HTTPVersion version, HTTPStatusCode statusCode)
|
||||
{
|
||||
// If we are creating a second response for the same request, make sure and
|
||||
// deallocate memory for old response and allocate fresh memory
|
||||
if (fResponseFormatter != NULL)
|
||||
{
|
||||
if(fResponseHeader->Ptr != NULL)
|
||||
delete fResponseHeader->Ptr;
|
||||
delete fResponseHeader;
|
||||
delete fResponseFormatter;
|
||||
}
|
||||
|
||||
// Allocate memory for the response when you first create it
|
||||
char* responseString = NEW char[kMinHeaderSizeInBytes];
|
||||
fResponseHeader = NEW StrPtrLen(responseString, kMinHeaderSizeInBytes);
|
||||
fResponseFormatter = NEW ResizeableStringFormatter(fResponseHeader->Ptr, fResponseHeader->Len);
|
||||
|
||||
//make a partial header for the given version and status code
|
||||
PutStatusLine(fResponseFormatter, statusCode, version);
|
||||
Assert(fSvrHeader.Ptr != NULL);
|
||||
fResponseFormatter->Put(fSvrHeader);
|
||||
fResponseFormatter->PutEOL();
|
||||
fResponseHeader->Len = fResponseFormatter->GetCurrentOffset();
|
||||
}
|
||||
|
||||
StrPtrLen* HTTPRequest::GetCompleteResponseHeader()
|
||||
{
|
||||
fResponseFormatter->PutEOL();
|
||||
fResponseHeader->Len = fResponseFormatter->GetCurrentOffset();
|
||||
return fResponseHeader;
|
||||
}
|
||||
|
||||
void HTTPRequest::AppendResponseHeader(HTTPHeader inHeader, StrPtrLen* inValue)
|
||||
{
|
||||
fResponseFormatter->Put(*(HTTPProtocol::GetHeaderString(inHeader)));
|
||||
fResponseFormatter->Put(sColonSpace);
|
||||
fResponseFormatter->Put(*inValue);
|
||||
fResponseFormatter->PutEOL();
|
||||
fResponseHeader->Len = fResponseFormatter->GetCurrentOffset();
|
||||
}
|
||||
|
||||
void HTTPRequest::AppendContentLengthHeader(UInt64 length_64bit)
|
||||
{
|
||||
char* contentLength = NEW char[256];
|
||||
qtss_sprintf(contentLength, "%"_64BITARG_"d", length_64bit);
|
||||
StrPtrLen contentLengthPtr(contentLength);
|
||||
AppendResponseHeader(httpContentLengthHeader, &contentLengthPtr);
|
||||
}
|
||||
|
||||
void HTTPRequest::AppendContentLengthHeader(UInt32 length_32bit)
|
||||
{
|
||||
char* contentLength = NEW char[256];
|
||||
qtss_sprintf(contentLength, "%"_U32BITARG_"", length_32bit);
|
||||
StrPtrLen contentLengthPtr(contentLength);
|
||||
AppendResponseHeader(httpContentLengthHeader, &contentLengthPtr);
|
||||
}
|
||||
|
||||
void HTTPRequest::AppendConnectionCloseHeader()
|
||||
{
|
||||
AppendResponseHeader(httpConnectionHeader, &sCloseString);
|
||||
}
|
||||
|
||||
void HTTPRequest::AppendConnectionKeepAliveHeader()
|
||||
{
|
||||
AppendResponseHeader(httpConnectionHeader, &sKeepAliveString);
|
||||
}
|
||||
|
||||
void HTTPRequest::AppendDateAndExpiresFields()
|
||||
{
|
||||
Assert(OSThread::GetCurrent() != NULL);
|
||||
DateBuffer* theDateBuffer = OSThread::GetCurrent()->GetDateBuffer();
|
||||
theDateBuffer->InexactUpdate(); // Update the date buffer to the current date & time
|
||||
StrPtrLen theDate(theDateBuffer->GetDateBuffer(), DateBuffer::kDateBufferLen);
|
||||
|
||||
// Append dates, and have this response expire immediately
|
||||
this->AppendResponseHeader(httpDateHeader, &theDate);
|
||||
this->AppendResponseHeader(httpExpiresHeader, &theDate);
|
||||
}
|
||||
|
||||
void HTTPRequest::AppendDateField()
|
||||
{
|
||||
Assert(OSThread::GetCurrent() != NULL);
|
||||
DateBuffer* theDateBuffer = OSThread::GetCurrent()->GetDateBuffer();
|
||||
theDateBuffer->InexactUpdate(); // Update the date buffer to the current date & time
|
||||
StrPtrLen theDate(theDateBuffer->GetDateBuffer(), DateBuffer::kDateBufferLen);
|
||||
|
||||
// Append date
|
||||
this->AppendResponseHeader(httpDateHeader, &theDate);
|
||||
}
|
||||
|
||||
time_t HTTPRequest::ParseIfModSinceHeader()
|
||||
{
|
||||
time_t theIfModSinceDate = (time_t) DateTranslator::ParseDate(&fFieldValues[httpIfModifiedSinceHeader]);
|
||||
return theIfModSinceDate;
|
||||
}
|
137
HTTPUtilitiesLib/HTTPRequest.h
Normal file
137
HTTPUtilitiesLib/HTTPRequest.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
#ifndef __HTTPREQUEST_H__
|
||||
#define __HTTPREQUEST_H__
|
||||
|
||||
#include "HTTPProtocol.h"
|
||||
#include "StrPtrLen.h"
|
||||
#include "StringParser.h"
|
||||
#include "ResizeableStringFormatter.h"
|
||||
#include "OSHeaders.h"
|
||||
#include "QTSS.h"
|
||||
|
||||
class HTTPRequest
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
HTTPRequest(StrPtrLen* serverHeader, StrPtrLen* requestPtr);
|
||||
|
||||
// This cosntructor is used when the request has been parsed and thrown away
|
||||
// and the response has to be created
|
||||
HTTPRequest(StrPtrLen* serverHeader);
|
||||
|
||||
// Destructor
|
||||
virtual ~HTTPRequest();
|
||||
|
||||
// Should be called before accessing anything in the request header
|
||||
// Calls ParseRequestLine and ParseHeaders
|
||||
QTSS_Error Parse();
|
||||
|
||||
// Basic access methods for the HTTP method, the absolute request URI,
|
||||
// the host name from URI, the relative request URI, the request file path,
|
||||
// the HTTP version, the Status code, the keep-alive tag.
|
||||
HTTPMethod GetMethod(){ return fMethod; }
|
||||
StrPtrLen* GetRequestLine(){ return &fRequestLine; }
|
||||
StrPtrLen* GetRequestAbsoluteURI(){ return &fAbsoluteURI; }
|
||||
StrPtrLen* GetSchemefromAbsoluteURI(){ return &fAbsoluteURIScheme; }
|
||||
StrPtrLen* GetHostfromAbsoluteURI(){ return &fHostHeader; }
|
||||
StrPtrLen* GetRequestRelativeURI(){ return &fRelativeURI; }
|
||||
char* GetRequestPath(){ return fRequestPath; }
|
||||
HTTPVersion GetVersion(){ return fVersion; }
|
||||
HTTPStatusCode GetStatusCode(){ return fStatusCode; }
|
||||
Bool16 IsRequestKeepAlive(){ return fRequestKeepAlive; }
|
||||
|
||||
// If header field exists in the request, it will be found in the dictionary
|
||||
// and the value returned. Otherwise, NULL is returned.
|
||||
StrPtrLen* GetHeaderValue(HTTPHeader inHeader);
|
||||
|
||||
// Creates a header with the corresponding version and status code
|
||||
void CreateResponseHeader(HTTPVersion version, HTTPStatusCode statusCode);
|
||||
|
||||
// To append response header fields as appropriate
|
||||
void AppendResponseHeader(HTTPHeader inHeader, StrPtrLen* inValue);
|
||||
void AppendDateAndExpiresFields();
|
||||
void AppendDateField();
|
||||
void AppendConnectionCloseHeader();
|
||||
void AppendConnectionKeepAliveHeader();
|
||||
void AppendContentLengthHeader(UInt64 length_64bit);
|
||||
void AppendContentLengthHeader(UInt32 length_32bit);
|
||||
|
||||
// Returns the completed response header by appending CRLF to the end of the header
|
||||
// fields buffer
|
||||
StrPtrLen* GetCompleteResponseHeader();
|
||||
|
||||
// Parse if-modified-since header
|
||||
time_t ParseIfModSinceHeader();
|
||||
|
||||
private:
|
||||
enum { kMinHeaderSizeInBytes = 512 };
|
||||
|
||||
// Gets the method, version and calls ParseURI
|
||||
QTSS_Error ParseRequestLine(StringParser* parser);
|
||||
// Parses the URI to get absolute and relative URIs, the host name and the file path
|
||||
QTSS_Error ParseURI(StringParser* parser);
|
||||
// Parses the headers and adds them into a dictionary
|
||||
// Also calls SetKeepAlive with the Connection header field's value if it exists
|
||||
QTSS_Error ParseHeaders(StringParser* parser);
|
||||
|
||||
// Sets fRequestKeepAlive
|
||||
void SetKeepAlive(StrPtrLen* keepAliveValue);
|
||||
// Used in initialize and CreateResponseHeader
|
||||
void PutStatusLine(StringFormatter* putStream, HTTPStatusCode status, HTTPVersion version);
|
||||
//For writing into the premade headers
|
||||
StrPtrLen* GetServerHeader(){ return &fSvrHeader; }
|
||||
|
||||
// Complete request and response headers
|
||||
StrPtrLen fRequestHeader;
|
||||
ResizeableStringFormatter* fResponseFormatter;
|
||||
StrPtrLen* fResponseHeader;
|
||||
|
||||
// Private members
|
||||
HTTPMethod fMethod;
|
||||
HTTPVersion fVersion;
|
||||
|
||||
StrPtrLen fRequestLine;
|
||||
|
||||
// For the URI (fAbsoluteURI and fRelativeURI are the same if the URI is of the form "/path")
|
||||
StrPtrLen fAbsoluteURI; // If it is of the form "http://foo.bar.com/path"
|
||||
StrPtrLen fRelativeURI; // If it is of the form "/path"
|
||||
|
||||
// If it is an absolute URI, these fields will be filled in
|
||||
// "http://foo.bar.com/path" => fAbsoluteURIScheme = "http", fHostHeader = "foo.bar.com",
|
||||
// fRequestPath = "path"
|
||||
StrPtrLen fAbsoluteURIScheme;
|
||||
StrPtrLen fHostHeader; // If the full url is given in the request line
|
||||
char* fRequestPath; // Also contains the query string
|
||||
|
||||
HTTPStatusCode fStatusCode;
|
||||
Bool16 fRequestKeepAlive; // Keep-alive information in the client request
|
||||
StrPtrLen fFieldValues[httpNumHeaders]; // Array of header field values parsed from the request
|
||||
StrPtrLen fSvrHeader; // Server header set up at initialization
|
||||
static StrPtrLen sColonSpace;
|
||||
static UInt8 sURLStopConditions[];
|
||||
};
|
||||
|
||||
#endif // __HTTPREQUEST_H__
|
Loading…
Add table
Add a link
Reference in a new issue