/http_server/stack/parser/AWSHttpMessageParser.h

http://github.com/jtblatt/duderino · C Header · 148 lines · 43 code · 29 blank · 76 comment · 0 complexity · f7b878a0c1181b7435456233b32a438b MD5 · raw file

  1. /* Copyright (c) 2009 Yahoo! Inc. All rights reserved.
  2. * The copyrights embodied in the content of this file are licensed by Yahoo! Inc.
  3. * under the BSD (revised) open source license.
  4. */
  5. #ifndef AWS_HTTP_MESSAGE_PARSER_H
  6. #define AWS_HTTP_MESSAGE_PARSER_H
  7. #ifndef ESF_DISCARD_ALLOCATOR_H
  8. #include <ESFDiscardAllocator.h>
  9. #endif
  10. #ifndef ESF_BUFFER_H
  11. #include <ESFBuffer.h>
  12. #endif
  13. #ifndef AWS_HTTP_MESSAGE_H
  14. #include <AWSHttpMessage.h>
  15. #endif
  16. /**
  17. * Parses a HTTP message as defined in RFC 2616 and RFC 2396
  18. *
  19. * TODO handle 1.x versions other than 1.0 and 1.1
  20. */
  21. class AWSHttpMessageParser
  22. {
  23. public:
  24. /** Create a new message parser
  25. *
  26. * @param workingBuffer Temporary storage for parsing
  27. * @param allocator The discard allocator to use for allocating internal strings.
  28. */
  29. AWSHttpMessageParser(ESFBuffer *workingBuffer, ESFDiscardAllocator *allocator);
  30. virtual ~AWSHttpMessageParser();
  31. /**
  32. * Reset the parser
  33. */
  34. virtual void reset();
  35. /**
  36. * Incrementally parse a HTTP Message up to but not including the body.
  37. *
  38. * generic-message = start-line
  39. * *(message-header CRLF)
  40. * CRLF
  41. * [ message-body ]
  42. *
  43. * Caller should:
  44. * (1) Fill buffer, closing any idle sockets, enforcing any size limits.
  45. * (2) Parse buffer with this method. If ESF_AGAIN is returned, compact
  46. * buffer & mark. If error or ESF_SUCCESS returned, break.
  47. * (3) If no space in buffer, parser is jammed, break and close socket.
  48. * (4) Otherwise goto (1)
  49. *
  50. * @param inputBuffer The buffer to parse
  51. * @param message The http message to build
  52. * @return ESF_SUCCESS if successful, ESF_AGAIN if more data needs to be read,
  53. * another error code otherwise.
  54. */
  55. ESFError parseHeaders(ESFBuffer *inputBuffer, AWSHttpMessage *message);
  56. /**
  57. * Parse the body. Caller should keep calling this mehtod on a given input buffer
  58. * until it returns an error, ESF_AGAIN (buffer needs to be compacted and filled),
  59. * or the number of bytes to be read is 0 (EOF)
  60. *
  61. * @param inputBuffer A buffer full of body data to be parsed.
  62. * @param startingPosition If ESF_SUCCESS is returned, this will be set to the
  63. * starting position of the chunk to be read
  64. * @param chunkSize If ESF_SUCCESS is returned, this will be set to the number of
  65. * bytes that can be read after the starting position. If 0, then there is no
  66. * more data left in the body.
  67. * @return ESF_SUCCESS if successful, ESF_AGAIN if the buffer needs to be
  68. * compacted and filled, another error code otherwise.
  69. */
  70. ESFError parseBody(ESFBuffer *inputBuffer, int *startingPosition, int *chunkSize);
  71. /**
  72. * Skips any body trailer. Necessary only if the connection will be reused.
  73. *
  74. * @param inputBuffer A buffer full of data to be parsed
  75. * @return ESF_SUCCESS if successful, ESF_AGAIN if the buffer needs to be compacted
  76. * and filled, another error code otherwise.
  77. */
  78. ESFError skipTrailer(ESFBuffer *inputBuffer);
  79. protected:
  80. virtual ESFError parseStartLine(ESFBuffer *inputBuffer, AWSHttpMessage *message) = 0;
  81. virtual bool isBodyNotAllowed(AWSHttpMessage *message) = 0;
  82. // HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
  83. ESFError parseVersion(ESFBuffer *inputBuffer, AWSHttpMessage *message, bool clientMode);
  84. ESFBuffer *_workingBuffer;
  85. ESFDiscardAllocator *_allocator;
  86. int _state;
  87. ESFUInt64 _bodyBytesRemaining;
  88. private:
  89. // Disabled
  90. AWSHttpMessageParser(const AWSHttpMessageParser &parser);
  91. void operator=(const AWSHttpMessageParser &parser);
  92. // field-name = token
  93. ESFError parseFieldName(ESFBuffer *inputBuffer, AWSHttpMessage *message);
  94. // field-value = *( field-content | LWS )
  95. // field-content = <the OCTETs making up the field-value
  96. // and consisting of either *TEXT or combinations
  97. // of token, separators, and quoted-string>
  98. ESFError parseFieldValue(ESFBuffer *inputBuffer, AWSHttpMessage *message);
  99. // Chunked-Body = *chunk
  100. // last-chunk
  101. // trailer
  102. // CRLF
  103. ESFError parseChunkedBody(ESFBuffer *inputBuffer, int *startingPosition, int *chunkSize);
  104. // chunk-size = 1*HEX
  105. ESFError parseChunkSize(ESFBuffer *inputBuffer);
  106. // chunk = ... [ chunk-extension ] CRLF
  107. // chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
  108. // chunk-ext-name = token
  109. // chunk-ext-val = token | quoted-string
  110. ESFError parseChunkExtension(ESFBuffer *inputBuffer);
  111. // chunk-data = chunk-size(OCTET)
  112. ESFError parseChunkData(ESFBuffer *inputBuffer, int *startingPosition, int *chunkSize);
  113. // chunk = ... CRLF
  114. ESFError parseEndChunk(ESFBuffer *inputBuffer);
  115. ESFError parseMultipartBody(ESFBuffer *inputBuffer, int *startingPosition, int *chunkSize);
  116. ESFError parseUnencodedBody(ESFBuffer *inputBuffer, int *startingPosition, int *chunkSize);
  117. ESFError postParse(AWSHttpMessage *message);
  118. };
  119. #endif