diff --git a/quic/core/http/http_decoder.cc b/quic/core/http/http_decoder.cc
new file mode 100644
index 0000000..e697821
--- /dev/null
+++ b/quic/core/http/http_decoder.cc
@@ -0,0 +1,411 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/http/http_decoder.h"
+#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_fallthrough.h"
+
+namespace quic {
+
+namespace {
+
+// Create a mask that sets the last |num_bits| to 1 and the rest to 0.
+inline uint8_t GetMaskFromNumBits(uint8_t num_bits) {
+  return (1u << num_bits) - 1;
+}
+
+// Extract |num_bits| from |flags| offset by |offset|.
+uint8_t ExtractBits(uint8_t flags, uint8_t num_bits, uint8_t offset) {
+  return (flags >> offset) & GetMaskFromNumBits(num_bits);
+}
+
+// Length of the type field of HTTP/3 frames.
+static const QuicByteCount kFrameTypeLength = 1;
+
+}  // namespace
+
+HttpDecoder::HttpDecoder()
+    : visitor_(nullptr),
+      state_(STATE_READING_FRAME_LENGTH),
+      current_frame_type_(0),
+      current_length_field_size_(0),
+      remaining_length_field_length_(0),
+      current_frame_length_(0),
+      remaining_frame_length_(0),
+      error_(QUIC_NO_ERROR),
+      error_detail_(""),
+      has_payload_(false) {}
+
+HttpDecoder::~HttpDecoder() {}
+
+QuicByteCount HttpDecoder::ProcessInput(const char* data, QuicByteCount len) {
+  has_payload_ = false;
+  QuicDataReader reader(data, len);
+  while (error_ == QUIC_NO_ERROR && reader.BytesRemaining() != 0) {
+    switch (state_) {
+      case STATE_READING_FRAME_LENGTH:
+        ReadFrameLength(&reader);
+        break;
+      case STATE_READING_FRAME_TYPE:
+        ReadFrameType(&reader);
+        break;
+      case STATE_READING_FRAME_PAYLOAD:
+        ReadFramePayload(&reader);
+        break;
+      case STATE_ERROR:
+        break;
+      default:
+        QUIC_BUG << "Invalid state: " << state_;
+    }
+  }
+
+  if (error_ != QUIC_NO_ERROR) {
+    return 0;
+  }
+
+  return len - reader.BytesRemaining();
+}
+
+void HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
+  DCHECK_NE(0u, reader->BytesRemaining());
+  BufferFrameLength(reader);
+  if (remaining_length_field_length_ != 0) {
+    return;
+  }
+  QuicDataReader length_reader(length_buffer_.data(),
+                               current_length_field_size_);
+  if (!length_reader.ReadVarInt62(&current_frame_length_)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame length");
+    visitor_->OnError(this);
+    return;
+  }
+
+  state_ = STATE_READING_FRAME_TYPE;
+  remaining_frame_length_ = current_frame_length_;
+}
+
+void HttpDecoder::ReadFrameType(QuicDataReader* reader) {
+  DCHECK_NE(0u, reader->BytesRemaining());
+  if (!reader->ReadUInt8(&current_frame_type_)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame type");
+    return;
+  }
+
+  state_ = STATE_READING_FRAME_PAYLOAD;
+}
+
+void HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
+  DCHECK_NE(0u, reader->BytesRemaining());
+  switch (current_frame_type_) {
+    case 0x0: {  // DATA
+      if (current_frame_length_ == remaining_frame_length_) {
+        visitor_->OnDataFrameStart(
+            Http3FrameLengths(current_length_field_size_ + kFrameTypeLength,
+                              current_frame_length_));
+      }
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      QuicStringPiece payload;
+      if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read data");
+        return;
+      }
+      has_payload_ = true;
+      visitor_->OnDataFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      if (remaining_frame_length_ == 0) {
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+        visitor_->OnDataFrameEnd();
+      }
+      return;
+    }
+    case 0x1: {  // HEADERS
+      if (current_frame_length_ == remaining_frame_length_) {
+        visitor_->OnHeadersFrameStart();
+      }
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      QuicStringPiece payload;
+      if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read data");
+        return;
+      }
+      visitor_->OnHeadersFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      if (remaining_frame_length_ == 0) {
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+        visitor_->OnHeadersFrameEnd(current_frame_length_);
+      }
+      return;
+    }
+    case 0x2: {  // PRIORITY
+      // TODO(rch): avoid buffering if the entire frame is present, and
+      // instead parse directly out of |reader|.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        PriorityFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        if (!ParsePriorityFrame(&reader, &frame)) {
+          return;
+        }
+        visitor_->OnPriorityFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+    case 0x3: {  // CANCEL_PUSH
+      // TODO(rch): Handle partial delivery.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        CancelPushFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        if (!reader.ReadVarInt62(&frame.push_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+          return;
+        }
+        visitor_->OnCancelPushFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+    case 0x4: {  // SETTINGS
+      // TODO(rch): Handle overly large SETTINGS frames. Either:
+      // 1. Impose a limit on SETTINGS frame size, and close the connection if
+      //    exceeded
+      // 2. Implement a streaming parsing mode.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        SettingsFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        if (!ParseSettingsFrame(&reader, &frame)) {
+          return;
+        }
+        visitor_->OnSettingsFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+    case 0x5: {  // PUSH_PROMISE
+      if (current_frame_length_ == remaining_frame_length_) {
+        QuicByteCount bytes_remaining = reader->BytesRemaining();
+        PushId push_id;
+        // TODO(rch): Handle partial delivery of this field.
+        if (!reader->ReadVarInt62(&push_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+          return;
+        }
+        remaining_frame_length_ -= bytes_remaining - reader->BytesRemaining();
+        visitor_->OnPushPromiseFrameStart(push_id);
+      }
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader->BytesRemaining());
+      if (bytes_to_read == 0) {
+        return;
+      }
+      QuicStringPiece payload;
+      if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read data");
+        return;
+      }
+      visitor_->OnPushPromiseFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      if (remaining_frame_length_ == 0) {
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+        visitor_->OnPushPromiseFrameEnd();
+      }
+      return;
+    }
+    case 0x7: {  // GOAWAY
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        GoAwayFrame frame;
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        uint64_t stream_id;
+        if (!reader.ReadVarInt62(&stream_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read GOAWAY stream_id");
+          return;
+        }
+        frame.stream_id = stream_id;
+        visitor_->OnGoAwayFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+
+    case 0xD: {  // MAX_PUSH_ID
+      // TODO(rch): Handle partial delivery.
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ == 0) {
+        QuicDataReader reader(buffer_.data(), current_frame_length_);
+        MaxPushIdFrame frame;
+        if (!reader.ReadVarInt62(&frame.push_id)) {
+          RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+          return;
+        }
+        visitor_->OnMaxPushIdFrame(frame);
+        state_ = STATE_READING_FRAME_LENGTH;
+        current_length_field_size_ = 0;
+      }
+      return;
+    }
+
+    case 0xE: {  // DUPLICATE_PUSH
+      BufferFramePayload(reader);
+      if (remaining_frame_length_ != 0) {
+        return;
+      }
+      QuicDataReader reader(buffer_.data(), current_frame_length_);
+      DuplicatePushFrame frame;
+      if (!reader.ReadVarInt62(&frame.push_id)) {
+        RaiseError(QUIC_INTERNAL_ERROR, "Unable to read push_id");
+        return;
+      }
+      visitor_->OnDuplicatePushFrame(frame);
+      state_ = STATE_READING_FRAME_LENGTH;
+      current_length_field_size_ = 0;
+      return;
+    }
+    // Reserved frame types.
+    // TODO(rch): Since these are actually the same behavior as the
+    // default, we probably don't need to special case them here?
+    case 0xB:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 2:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 3:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 4:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 5:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 6:
+      QUIC_FALLTHROUGH_INTENDED;
+    case 0xB + 0x1F * 7:
+      QUIC_FALLTHROUGH_INTENDED;
+    default:
+      DiscardFramePayload(reader);
+  }
+}
+
+void HttpDecoder::DiscardFramePayload(QuicDataReader* reader) {
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  QuicStringPiece payload;
+  if (!reader->ReadStringPiece(&payload, bytes_to_read)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame payload");
+    return;
+  }
+  remaining_frame_length_ -= payload.length();
+  if (remaining_frame_length_ == 0) {
+    state_ = STATE_READING_FRAME_LENGTH;
+    current_length_field_size_ = 0;
+  }
+}
+
+void HttpDecoder::BufferFramePayload(QuicDataReader* reader) {
+  if (current_frame_length_ == remaining_frame_length_) {
+    buffer_.erase(buffer_.size());
+    buffer_.reserve(current_frame_length_);
+  }
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_frame_length_, reader->BytesRemaining());
+  if (!reader->ReadBytes(
+          &(buffer_[0]) + current_frame_length_ - remaining_frame_length_,
+          bytes_to_read)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame payload");
+    return;
+  }
+  remaining_frame_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
+  if (current_length_field_size_ == 0) {
+    current_length_field_size_ = reader->PeekVarInt62Length();
+    if (current_length_field_size_ == 0) {
+      RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame length");
+      visitor_->OnError(this);
+      return;
+    }
+    remaining_length_field_length_ = current_length_field_size_;
+  }
+  if (current_length_field_size_ == remaining_length_field_length_) {
+    length_buffer_.erase(length_buffer_.size());
+    length_buffer_.reserve(current_length_field_size_);
+  }
+  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+      remaining_length_field_length_, reader->BytesRemaining());
+  if (!reader->ReadBytes(&(length_buffer_[0]) + current_length_field_size_ -
+                             remaining_length_field_length_,
+                         bytes_to_read)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read frame length");
+    visitor_->OnError(this);
+    return;
+  }
+  remaining_length_field_length_ -= bytes_to_read;
+}
+
+void HttpDecoder::RaiseError(QuicErrorCode error, QuicString error_detail) {
+  state_ = STATE_ERROR;
+  error_ = error;
+  error_detail_ = std::move(error_detail);
+}
+
+bool HttpDecoder::ParsePriorityFrame(QuicDataReader* reader,
+                                     PriorityFrame* frame) {
+  uint8_t flags;
+  if (!reader->ReadUInt8(&flags)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read priority frame flags");
+    return false;
+  }
+
+  frame->prioritized_type =
+      static_cast<PriorityElementType>(ExtractBits(flags, 2, 6));
+  frame->dependency_type =
+      static_cast<PriorityElementType>(ExtractBits(flags, 2, 4));
+  frame->exclusive = flags % 2 == 1;
+  if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read prioritized_element_id");
+    return false;
+  }
+  if (!reader->ReadVarInt62(&frame->element_dependency_id)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read element_dependency_id");
+    return false;
+  }
+  if (!reader->ReadUInt8(&frame->weight)) {
+    RaiseError(QUIC_INTERNAL_ERROR, "Unable to read priority frame weight");
+    return false;
+  }
+  return true;
+}
+
+bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
+                                     SettingsFrame* frame) {
+  while (!reader->IsDoneReading()) {
+    uint16_t id;
+    if (!reader->ReadUInt16(&id)) {
+      RaiseError(QUIC_INTERNAL_ERROR,
+                 "Unable to read settings frame identifier");
+      return false;
+    }
+    uint64_t content;
+    if (!reader->ReadVarInt62(&content)) {
+      RaiseError(QUIC_INTERNAL_ERROR, "Unable to read settings frame content");
+      return false;
+    }
+    frame->values[id] = content;
+  }
+  return true;
+}
+
+}  // namespace quic
