text:
// Copyright 2022 TF.Text Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef TENSORFLOW_LITE_SUPPORT_CUSTOM_OPS_KERNEL_SENTENCEPIECE_OPTIMIZED_ENCODER_H_
#define TENSORFLOW_LITE_SUPPORT_CUSTOM_OPS_KERNEL_SENTENCEPIECE_OPTIMIZED_ENCODER_H_

// Sentencepiece encoder optimized with memmapped model.

#include <string>
#include <tuple>
#include <vector>

#include "tensorflow_text/core/kernels/sentencepiece/encoder_config_generated.h"

namespace tensorflow {
namespace text {
namespace sentencepiece {

enum class EncoderResultType { SUCCESS = 0, WRONG_CONFIG = 1 };

struct EncoderResult {
  EncoderResultType type = EncoderResultType::SUCCESS;
  std::vector<int> codes;
  std::vector<int> offsets;
};
std::tuple<std::string, std::vector<int>> NormalizeString(
    const std::string& in_string, const EncoderConfig& config);

// Encodes one string and returns ids and offsets. Takes the configuration as a
// type-erased buffer.
EncoderResult EncodeString(const std::string& string, const void* config_buffer,
                           bool add_bos, bool add_eos, bool reverse);

}  // namespace sentencepiece
}  // namespace text
}  // namespace tensorflow

#endif  // TENSORFLOW_LITE_SUPPORT_CUSTOM_OPS_KERNEL_SENTENCEPIECE_OPTIMIZED_ENCODER_H_


text:
from __future__ import unicode_literals, absolute_import

import unittest

import responses
from linebot import (
    LineBotApi
)
from linebot.exceptions import (
    LineBotApiError
)
from linebot.models import (
    TextSendMessage
)

class TestLineBotApi(unittest.TestCase):
    def setUp(self):
        self.tested = LineBotApi('channel_secret')

    @responses.activate
    def test_error_handle(self):
        responses.add(
            responses.POST,
            LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/message/push',
            json={
                "message": "Invalid reply token"
            },
            status=401
        )

        try:
            self.tested.push_message('to', TextSendMessage(text='hoge'))
        except LineBotApiError as e:
            self.assertEqual(e.status_code, 401)
            self.assertEqual(e.error.message, 'Invalid reply token')

    @responses.activate
    def test_error_with_detail_handle(self):
        responses.add(
            responses.POST,
            LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/message/push',
            json={
                "message": "The request body has 2 error(s)",
                "details": [
                    {
                        "message": "May not be empty",
                        "property": "messages[0].text"
                    },
                    {
                        "message": "Must be one of the following values: [text"
                                   ", image, video, audio, location, sticker, "
                                   "richmessage, template, imagemap]",
                        "property": "messages[1].type"
                    }
                ]
            },
            status=400
        )

        try:
            self.tested.push_message(
                'to',
                TextSendMessage(text='hoge')
            )
        except LineBotApiError as e:
            self.assertEqual(e.status_code, 400)
            self.assertEqual(e.error.message, 'The request body has 2 error(s)')
            self.assertEqual(e.error.details[0].message, 'May not be empty')
            self.assertEqual(e.error.details[0].property, 'messages[0].text')
            self.assertEqual(
                e.error.details[1].message, "Must be one of the following "
                                            "values: [text"
                                            ", image, video, audio, "
                                            "location, sticker, "
                                            "richmessage, template, imagemap]"
            )
            self.assertEqual(e.error.details[1].property, 'messages[1].type')

    @responses.activate
    def test_error_handle_get_message_content(self):
        responses.add(
            responses.GET,
            LineBotApi.DEFAULT_API_ENDPOINT + '/v2/bot/message/1/content',
            json={
                "message": "Invalid reply token"
            },
            status=404
        )

        try:
            self.tested.get_message_content(1)
        except LineBotApiError as e:
            self.assertEqual(e.status_code, 404)
            self.assertEqual(e.error.message, 'Invalid reply token')

if __name__ == '__main__':
    unittest.main()

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>de.hska.lkit</groupId>
	<artifactId>spring-web-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-web-demo</name>
	<description>VS2 Lab Vorstudie</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.3.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>

		<!-- Spring-Boot-Starter Deps -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
			<version>1.5.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

		<!--WebJars -->

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			</dependency>

		<!-- Websocket -->
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>0.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!-- Jquery & Bootstrap -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.1.0</version>
        </dependency>

        <!-- JSON Parsing -->
        <dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-core</artifactId>
		</dependency>
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>


text:
// Template Source: BaseMethodCollectionResponse.java.tt
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All Rights Reserved.  Licensed under the MIT License.  See License in the project root for license information.
// ------------------------------------------------------------------------------

package com.microsoft.graph.requests;
import com.microsoft.graph.models.DirectoryObject;

import javax.annotation.Nullable;
import javax.annotation.Nonnull;
import com.microsoft.graph.http.BaseCollectionResponse;

// **NOTE** This file was generated by a tool and any changes will be overwritten.

/**
 * The class for the Directory Object Get By Ids Collection Response.
 */
public class DirectoryObjectGetByIdsCollectionResponse extends BaseCollectionResponse<DirectoryObject> {
}


text:
#pragma once

#include <stdexcept>

namespace Pistache::Tcp
{

    class SocketError : public std::runtime_error
    {
    public:
        explicit SocketError(const char* what_arg)
            : std::runtime_error(what_arg)
        { }
    };

    class ServerError : public std::runtime_error
    {
    public:
        explicit ServerError(const char* what_arg)
            : std::runtime_error(what_arg)
        { }
    };

} // namespace Pistache::Tcp


text:
// Copyright 2021 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 "gpu/command_buffer/service/shared_image_backing_factory_raw_draw.h"

#include "base/logging.h"
#include "base/thread_annotations.h"
#include "cc/paint/paint_op_buffer.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image_representation.h"

namespace gpu {

class SharedImageBackingFactoryRawDraw;

namespace {

class RawDrawBacking : public ClearTrackingSharedImageBacking {
 public:
  RawDrawBacking(const Mailbox& mailbox,
                 viz::ResourceFormat format,
                 const gfx::Size& size,
                 const gfx::ColorSpace& color_space,
                 GrSurfaceOrigin surface_origin,
                 SkAlphaType alpha_type,
                 uint32_t usage,
                 size_t estimated_size)
      : ClearTrackingSharedImageBacking(mailbox,
                                        format,
                                        size,
                                        color_space,
                                        surface_origin,
                                        alpha_type,
                                        usage,
                                        estimated_size,
                                        true /* is_thread_safe */) {}

  ~RawDrawBacking() override {
    AutoLock auto_lock(this);
    DCHECK_EQ(read_count_, 0);
    DCHECK(!is_write_);
    ResetPaintOpBuffer();
  }

  // SharedImageBacking implementation.
  bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override {
    NOTREACHED() << "Not supported.";
    return false;
  }

  void Update(std::unique_ptr<gfx::GpuFence> in_fence) override {
    NOTREACHED() << "Not supported.";
  }

  void OnMemoryDump(const std::string& dump_name,
                    base::trace_event::MemoryAllocatorDump* dump,
                    base::trace_event::ProcessMemoryDump* pmd,
                    uint64_t client_tracing_id) override {}

 protected:
  std::unique_ptr<SharedImageRepresentationRaster> ProduceRaster(
      SharedImageManager* manager,
      MemoryTypeTracker* tracker) override;

 private:
  class RepresentationRaster;

  void ResetPaintOpBuffer() {
    if (!paint_op_buffer_) {
      DCHECK(!clear_color_);
      DCHECK(!paint_op_release_callback_);
      return;
    }

    final_msaa_count_ = 0;
    clear_color_.reset();
    paint_op_buffer_->Reset();

    if (paint_op_release_callback_)
      std::move(paint_op_release_callback_).Run();
  }

  int32_t final_msaa_count_ = 0;
  absl::optional<SkColor> clear_color_;
  sk_sp<cc::PaintOpBuffer> paint_op_buffer_;
  base::OnceClosure paint_op_release_callback_;

  bool is_write_ GUARDED_BY(lock_) = false;
  int read_count_ GUARDED_BY(lock_) = 0;
};

class RawDrawBacking::RepresentationRaster
    : public SharedImageRepresentationRaster {
 public:
  RepresentationRaster(SharedImageManager* manager,
                       SharedImageBacking* backing,
                       MemoryTypeTracker* tracker)
      : SharedImageRepresentationRaster(manager, backing, tracker) {}
  ~RepresentationRaster() override = default;

  cc::PaintOpBuffer* BeginReadAccess(
      absl::optional<SkColor>& clear_color) override {
    AutoLock auto_lock(raw_draw_backing());
    if (raw_draw_backing()->is_write_) {
      LOG(ERROR) << "The backing is being written.";
      return nullptr;
    }

    raw_draw_backing()->read_count_++;

    if (!raw_draw_backing()->paint_op_buffer_) {
      raw_draw_backing()->paint_op_buffer_ = sk_make_sp<cc::PaintOpBuffer>();
    }

    clear_color = raw_draw_backing()->clear_color_;
    return raw_draw_backing()->paint_op_buffer_.get();
  }

  void EndReadAccess() override {
    AutoLock auto_lock(raw_draw_backing());
    DCHECK_GE(raw_draw_backing()->read_count_, 0);
    DCHECK(!raw_draw_backing()->is_write_);
    raw_draw_backing()->read_count_--;
  }

  cc::PaintOpBuffer* BeginWriteAccess(
      int final_msaa_count,
      const SkSurfaceProps& surface_props,
      const absl::optional<SkColor>& clear_color) override {
    AutoLock auto_lock(raw_draw_backing());
    if (raw_draw_backing()->read_count_) {
      LOG(ERROR) << "The backing is being read.";
      return nullptr;
    }

    if (raw_draw_backing()->is_write_) {
      LOG(ERROR) << "The backing is being written.";
      return nullptr;
    }

    raw_draw_backing()->is_write_ = true;

    raw_draw_backing()->ResetPaintOpBuffer();
    if (!raw_draw_backing()->paint_op_buffer_) {
      raw_draw_backing()->paint_op_buffer_ = sk_make_sp<cc::PaintOpBuffer>();
    }
    raw_draw_backing()->final_msaa_count_ = final_msaa_count;
    raw_draw_backing()->clear_color_ = clear_color;

    return raw_draw_backing()->paint_op_buffer_.get();
  }

  void EndWriteAccess(base::OnceClosure callback) override {
    AutoLock auto_lock(raw_draw_backing());
    DCHECK_EQ(raw_draw_backing()->read_count_, 0);
    DCHECK(raw_draw_backing()->is_write_);

    raw_draw_backing()->is_write_ = false;

    if (callback) {
      DCHECK(!raw_draw_backing()->paint_op_release_callback_);
      raw_draw_backing()->paint_op_release_callback_ = std::move(callback);
    }
  }

 private:
  RawDrawBacking* raw_draw_backing() {
    return static_cast<RawDrawBacking*>(backing());
  }
};

std::unique_ptr<SharedImageRepresentationRaster> RawDrawBacking::ProduceRaster(
    SharedImageManager* manager,
    MemoryTypeTracker* tracker) {
  return std::make_unique<RepresentationRaster>(manager, this, tracker);
}

}  // namespace

SharedImageBackingFactoryRawDraw::SharedImageBackingFactoryRawDraw() = default;
SharedImageBackingFactoryRawDraw::~SharedImageBackingFactoryRawDraw() = default;

std::unique_ptr<SharedImageBacking>
SharedImageBackingFactoryRawDraw::CreateSharedImage(
    const Mailbox& mailbox,
    viz::ResourceFormat format,
    SurfaceHandle surface_handle,
    const gfx::Size& size,
    const gfx::ColorSpace& color_space,
    GrSurfaceOrigin surface_origin,
    SkAlphaType alpha_type,
    uint32_t usage,
    bool is_thread_safe) {
  DCHECK(!is_thread_safe);
  auto texture = std::make_unique<RawDrawBacking>(
      mailbox, format, size, color_space, surface_origin, alpha_type, usage,
      /*estimated_size=*/0);
  return texture;
}

std::unique_ptr<SharedImageBacking>
SharedImageBackingFactoryRawDraw::CreateSharedImage(
    const Mailbox& mailbox,
    viz::ResourceFormat format,
    const gfx::Size& size,
    const gfx::ColorSpace& color_space,
    GrSurfaceOrigin surface_origin,
    SkAlphaType alpha_type,
    uint32_t usage,
    base::span<const uint8_t> data) {
  NOTREACHED() << "Not supported";
  return nullptr;
}

std::unique_ptr<SharedImageBacking>
SharedImageBackingFactoryRawDraw::CreateSharedImage(
    const Mailbox& mailbox,
    int client_id,
    gfx::GpuMemoryBufferHandle handle,
    gfx::BufferFormat buffer_format,
    gfx::BufferPlane plane,
    SurfaceHandle surface_handle,
    const gfx::Size& size,
    const gfx::ColorSpace& color_space,
    GrSurfaceOrigin surface_origin,
    SkAlphaType alpha_type,
    uint32_t usage) {
  NOTREACHED() << "Not supported";
  return nullptr;
}

bool SharedImageBackingFactoryRawDraw::CanUseRawDrawBacking(
    uint32_t usage,
    GrContextType gr_context_type) const {
  // Ignore for mipmap usage.
  usage &= ~SHARED_IMAGE_USAGE_MIPMAP;

  auto kRawDrawBackingUsage =
      SHARED_IMAGE_USAGE_DISPLAY | SHARED_IMAGE_USAGE_RASTER |
      SHARED_IMAGE_USAGE_OOP_RASTERIZATION | SHARED_IMAGE_USAGE_RAW_DRAW;
  return usage == kRawDrawBackingUsage;
}

bool SharedImageBackingFactoryRawDraw::IsSupported(
    uint32_t usage,
    viz::ResourceFormat format,
    bool thread_safe,
    gfx::GpuMemoryBufferType gmb_type,
    GrContextType gr_context_type,
    bool* allow_legacy_mailbox,
    bool is_pixel_used) {
  if (!CanUseRawDrawBacking(usage, gr_context_type)) {
    return false;
  }

  if (is_pixel_used) {
    return false;
  }

  if (gmb_type != gfx::EMPTY_BUFFER) {
    return false;
  }

  *allow_legacy_mailbox = false;
  return true;
}

}  // namespace gpu


text:
require 'csv'
require 'singleton'

require 'monet/errors'

module Monet
  class PageLogger
    include Singleton
    extend Forwardable

    module Helpers
      def log_page(url, status)
        PageLogger.instance.add(url, status)
      end

      def failed?(url)
        PageLogger.instance.failed? url
      end
    end

    def initialize
      reset
    end

    def_delegators :@cache, :size, :length, :count, :[]

    def status_for(url)
      status = @cache[url]
      raise Monet::Errors::UnseenURL.new(url) unless status

      status
    end

    def add(url, status)
      @cache[normalize_url(url)] = status.to_i
    end

    def save(path)
      File.open(path, "w+") do |io|
        @cache.each do |k,v|
          io.puts "#{k},#{v}"
        end
      end
    end

    def self.load(path)
      logger = new
      CSV.foreach(path) do |k,v|
        logger.add(k,v)
      end

      logger
    end

    def reset
      @cache = {}
    end

    def self.reset
      instance.reset
    end

    def failures
      @cache.select {|k,v| failed? k }
    end

    def successes
      @cache.select {|k,v| succeeded? k }
    end

    def succeeded?(url)
      status_for(url) < 400
    end

    def failed?(url)
      !succeeded?(url)
    end

    private
    def normalize_url(url)
      url.to_s.chomp("/")
    end
  end
end


text:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menu_item_share_movie"
        android:title="@string/share_movie"
        android:icon="@drawable/ic_share_white_24dp"
        android:orderInCategory="100"
        app:showAsAction="ifRoom"/>
</menu>


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExpenseManager.Model
{
    /// <summary>
    /// The class of the income types
    /// </summary>
    public class IncomeType
    {
        /// <summary>
        /// the generated id for databases
        /// </summary>
        private int id { get; set; }
        /// <summary>
        /// the key of income type
        /// </summary>
        public string key { get; set; }
        /// <summary>
        /// the description of income type
        /// </summary>
        public string description { get; set; }

        /// <summary>
        /// the full constructor of income type
        /// </summary>
        /// <param name="key">the key of income type</param>
        /// <param name="description">the description of income type</param>
        public IncomeType(string key, string description)
        {
            this.key = key;
            this.description = description;
        }

        /// <summary>
        /// The default constructor
        /// </summary>
        public IncomeType() { }

        /// <summary>
        /// The ToString Method that will show the content of the income type
        /// </summary>
        /// <returns>the content of income type in this format: key - description</returns>
        public override string ToString()
        {
            return key + " - " + description;
        }
    }
}


text:
#include <string>

#include "webrtc/p2p/base/stun.h"
#include "webrtc/base/arraysize.h"
#include "webrtc/base/bytebuffer.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/messagedigest.h"
#include "webrtc/base/socketaddress.h"

namespace cricket {

class StunTest : public ::testing::Test {
 protected:
  void CheckStunHeader(const StunMessage& msg, StunMessageType expected_type,
                       size_t expected_length) {
    ASSERT_EQ(expected_type, msg.type());
    ASSERT_EQ(expected_length, msg.length());
  }

  void CheckStunTransactionID(const StunMessage& msg,
                              const unsigned char* expectedID, size_t length) {
    ASSERT_EQ(length, msg.transaction_id().size());
    ASSERT_EQ(length == kStunTransactionIdLength + 4, msg.IsLegacy());
    ASSERT_EQ(length == kStunTransactionIdLength, !msg.IsLegacy());
    ASSERT_EQ(0, memcmp(msg.transaction_id().c_str(), expectedID, length));
  }

  void CheckStunAddressAttribute(const StunAddressAttribute* addr,
                                 StunAddressFamily expected_family,
                                 int expected_port,
                                 rtc::IPAddress expected_address) {
    ASSERT_EQ(expected_family, addr->family());
    ASSERT_EQ(expected_port, addr->port());

    if (addr->family() == STUN_ADDRESS_IPV4) {
      in_addr v4_address = expected_address.ipv4_address();
      in_addr stun_address = addr->ipaddr().ipv4_address();
      ASSERT_EQ(0, memcmp(&v4_address, &stun_address, sizeof(stun_address)));
    } else if (addr->family() == STUN_ADDRESS_IPV6) {
      in6_addr v6_address = expected_address.ipv6_address();
      in6_addr stun_address = addr->ipaddr().ipv6_address();
      ASSERT_EQ(0, memcmp(&v6_address, &stun_address, sizeof(stun_address)));
    } else {
      ASSERT_TRUE(addr->family() == STUN_ADDRESS_IPV6 ||
                  addr->family() == STUN_ADDRESS_IPV4);
    }
  }

  size_t ReadStunMessageTestCase(StunMessage* msg,
                                 const unsigned char* testcase,
                                 size_t size) {
    const char* input = reinterpret_cast<const char*>(testcase);
    rtc::ByteBufferReader buf(input, size);
    if (msg->Read(&buf)) {
      // Returns the size the stun message should report itself as being
      return (size - 20);
    } else {
      return 0;
    }
  }
};

// Sample STUN packets with various attributes
// Gathered by wiresharking pjproject's pjnath test programs
// pjproject available at www.pjsip.org

static const unsigned char kStunMessageWithIPv6MappedAddress[] = {
  0x00, 0x01, 0x00, 0x18,  // message header
  0x21, 0x12, 0xa4, 0x42,  // transaction id
  0x29, 0x1f, 0xcd, 0x7c,
  0xba, 0x58, 0xab, 0xd7,
  0xf2, 0x41, 0x01, 0x00,
  0x00, 0x01, 0x00, 0x14,  // Address type (mapped), length
  0x00, 0x02, 0xb8, 0x81,  // family (IPv6), port
  0x24, 0x01, 0xfa, 0x00,  // an IPv6 address
  0x00, 0x04, 0x10, 0x00,
  0xbe, 0x30, 0x5b, 0xff,
  0xfe, 0xe5, 0x00, 0xc3
};

static const unsigned char kStunMessageWithIPv4MappedAddress[] = {
  0x01, 0x01, 0x00, 0x0c,   // binding response, length 12
  0x21, 0x12, 0xa4, 0x42,   // magic cookie
  0x29, 0x1f, 0xcd, 0x7c,   // transaction ID
  0xba, 0x58, 0xab, 0xd7,
  0xf2, 0x41, 0x01, 0x00,
  0x00, 0x01, 0x00, 0x08,  // Mapped, 8 byte length
  0x00, 0x01, 0x9d, 0xfc,  // AF_INET, unxor-ed port
  0xac, 0x17, 0x44, 0xe6   // IPv4 address
};

// Test XOR-mapped IP addresses:
static const unsigned char kStunMessageWithIPv6XorMappedAddress[] = {
  0x01, 0x01, 0x00, 0x18,  // message header (binding response)
  0x21, 0x12, 0xa4, 0x42,  // magic cookie (rfc5389)
  0xe3, 0xa9, 0x46, 0xe1,  // transaction ID
  0x7c, 0x00, 0xc2, 0x62,
  0x54, 0x08, 0x01, 0x00,
  0x00, 0x20, 0x00, 0x14,  // Address Type (XOR), length
  0x00, 0x02, 0xcb, 0x5b,  // family, XOR-ed port
  0x05, 0x13, 0x5e, 0x42,  // XOR-ed IPv6 address
  0xe3, 0xad, 0x56, 0xe1,
  0xc2, 0x30, 0x99, 0x9d,
  0xaa, 0xed, 0x01, 0xc3
};

static const unsigned char kStunMessageWithIPv4XorMappedAddress[] = {
  0x01, 0x01, 0x00, 0x0c,  // message header (binding response)
  0x21, 0x12, 0xa4, 0x42,  // magic cookie
  0x29, 0x1f, 0xcd, 0x7c,  // transaction ID
  0xba, 0x58, 0xab, 0xd7,
  0xf2, 0x41, 0x01, 0x00,
  0x00, 0x20, 0x00, 0x08,  // address type (xor), length
  0x00, 0x01, 0xfc, 0xb5,  // family (AF_INET), XOR-ed port
  0x8d, 0x05, 0xe0, 0xa4   // IPv4 address
};

// ByteString Attribute (username)
static const unsigned char kStunMessageWithByteStringAttribute[] = {
  0x00, 0x01, 0x00, 0x0c,
  0x21, 0x12, 0xa4, 0x42,
  0xe3, 0xa9, 0x46, 0xe1,
  0x7c, 0x00, 0xc2, 0x62,
  0x54, 0x08, 0x01, 0x00,
  0x00, 0x06, 0x00, 0x08,  // username attribute (length 8)
  0x61, 0x62, 0x63, 0x64,  // abcdefgh
  0x65, 0x66, 0x67, 0x68
};

// Message with an unknown but comprehensible optional attribute.
// Parsing should succeed despite this unknown attribute.
static const unsigned char kStunMessageWithUnknownAttribute[] = {
  0x00, 0x01, 0x00, 0x14,
  0x21, 0x12, 0xa4, 0x42,
  0xe3, 0xa9, 0x46, 0xe1,
  0x7c, 0x00, 0xc2, 0x62,
  0x54, 0x08, 0x01, 0x00,
  0x00, 0xaa, 0x00, 0x07,  // Unknown attribute, length 7 (needs padding!)
  0x61, 0x62, 0x63, 0x64,  // abcdefg + padding
  0x65, 0x66, 0x67, 0x00,
  0x00, 0x06, 0x00, 0x03,  // Followed by a known attribute we can
  0x61, 0x62, 0x63, 0x00   // check for (username of length 3)
};

// ByteString Attribute (username) with padding byte
static const unsigned char kStunMessageWithPaddedByteStringAttribute[] = {
  0x00, 0x01, 0x00, 0x08,
  0x21, 0x12, 0xa4, 0x42,
  0xe3, 0xa9, 0x46, 0xe1,
  0x7c, 0x00, 0xc2, 0x62,
  0x54, 0x08, 0x01, 0x00,
  0x00, 0x06, 0x00, 0x03,  // username attribute (length 3)
  0x61, 0x62, 0x63, 0xcc   // abc
};

// Message with an Unknown Attributes (uint16_t list) attribute.
static const unsigned char kStunMessageWithUInt16ListAttribute[] = {
  0x00, 0x01, 0x00, 0x0c,
  0x21, 0x12, 0xa4, 0x42,
  0xe3, 0xa9, 0x46, 0xe1,
  0x7c, 0x00, 0xc2, 0x62,
  0x54, 0x08, 0x01, 0x00,
  0x00, 0x0a, 0x00, 0x06,  // username attribute (length 6)
  0x00, 0x01, 0x10, 0x00,  // three attributes plus padding
  0xAB, 0xCU, 0xBE, 0xEF
};

// Error response message (unauthorized)
static const unsigned char kStunMessageWithErrorAttribute[] = {
  0x01, 0x11, 0x00, 0x14,
  0x21, 0x12, 0xa4, 0x42,
  0x29, 0x1f, 0xcd, 0x7c,
  0xba, 0x58, 0xab, 0xd7,
  0xf2, 0x41, 0x01, 0x00,
  0x00, 0x09, 0x00, 0x10,
  0x00, 0x00, 0x04, 0x01,
  0x55, 0x6e, 0x61, 0x75,
  0x74, 0x68, 0x6f, 0x72,
  0x69, 0x7a, 0x65, 0x64
};

static const unsigned char kStunMessageWithOriginAttribute[] = {
  0x00, 0x01, 0x00, 0x18,  // message header (binding request), length 24
  0x21, 0x12, 0xA4, 0x42,  // magic cookie
  0x29, 0x1f, 0xcd, 0x7c,  // transaction id
  0xba, 0x58, 0xab, 0xd7,
  0xf2, 0x41, 0x01, 0x00,
  0x80, 0x2f, 0x00, 0x12,  // origin attribute (length 18)
  0x68, 0x74, 0x74, 0x70,  // http://example.com
  0x3A, 0x2F, 0x2F, 0x65,
  0x78, 0x61, 0x6d, 0x70,
  0x6c, 0x65, 0x2e, 0x63,
  0x6f, 0x6d, 0x00, 0x00,
};

// Sample messages with an invalid length Field

// The actual length in bytes of the invalid messages (including STUN header)
static const int kRealLengthOfInvalidLengthTestCases = 32;

static const unsigned char kStunMessageWithZeroLength[] = {
  0x00, 0x01, 0x00, 0x00,  // length of 0 (last 2 bytes)
  0x21, 0x12, 0xA4, 0x42,  // magic cookie
  '0', '1', '2', '3',      // transaction id
  '4', '5', '6', '7',
  '8', '9', 'a', 'b',
  0x00, 0x20, 0x00, 0x08,  // xor mapped address
  0x00, 0x01, 0x21, 0x1F,
  0x21, 0x12, 0xA4, 0x53,
};

static const unsigned char kStunMessageWithExcessLength[] = {
  0x00, 0x01, 0x00, 0x55,  // length of 85
  0x21, 0x12, 0xA4, 0x42,  // magic cookie
  '0', '1', '2', '3',      // transaction id
  '4', '5', '6', '7',
  '8', '9', 'a', 'b',
  0x00, 0x20, 0x00, 0x08,  // xor mapped address
  0x00, 0x01, 0x21, 0x1F,
  0x21, 0x12, 0xA4, 0x53,
};

static const unsigned char kStunMessageWithSmallLength[] = {
  0x00, 0x01, 0x00, 0x03,  // length of 3
  0x21, 0x12, 0xA4, 0x42,  // magic cookie
  '0', '1', '2', '3',      // transaction id
  '4', '5', '6', '7',
  '8', '9', 'a', 'b',
  0x00, 0x20, 0x00, 0x08,  // xor mapped address
  0x00, 0x01, 0x21, 0x1F,
  0x21, 0x12, 0xA4, 0x53,
};

static const unsigned char kStunMessageWithBadHmacAtEnd[] = {
  0x00, 0x01, 0x00, 0x14,  // message length exactly 20
  0x21, 0x12, 0xA4, 0x42,  // magic cookie
  '0', '1', '2', '3',      // transaction ID
  '4', '5', '6', '7',
  '8', '9', 'a', 'b',
  0x00, 0x08, 0x00, 0x14,  // type=STUN_ATTR_MESSAGE_INTEGRITY, length=20
  '0', '0', '0', '0',      // We lied, there are only 16 bytes of HMAC.
  '0', '0', '0', '0',
  '0', '0', '0', '0',
  '0', '0', '0', '0',
};

// RTCP packet, for testing we correctly ignore non stun packet types.
// V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc
static const unsigned char kRtcpPacket[] = {
  0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55,
  0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09,
  0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56,
  0x00, 0x03, 0x73, 0x50,
};

// RFC5769 Test Vectors
// Software name (request):  "STUN test client" (without quotes)
// Software name (response): "test vector" (without quotes)
// Username:  "evtj:h6vY" (without quotes)
// Password:  "VOkJxbRl1RmTxUk/WvJxBt" (without quotes)
static const unsigned char kRfc5769SampleMsgTransactionId[] = {
  0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae
};
static const char kRfc5769SampleMsgClientSoftware[] = "STUN test client";
static const char kRfc5769SampleMsgServerSoftware[] = "test vector";
static const char kRfc5769SampleMsgUsername[] = "evtj:h6vY";
static const char kRfc5769SampleMsgPassword[] = "VOkJxbRl1RmTxUk/WvJxBt";
static const rtc::SocketAddress kRfc5769SampleMsgMappedAddress(
    "192.0.2.1", 32853);
static const rtc::SocketAddress kRfc5769SampleMsgIPv6MappedAddress(
    "2001:db8:1234:5678:11:2233:4455:6677", 32853);

static const unsigned char kRfc5769SampleMsgWithAuthTransactionId[] = {
  0x78, 0xad, 0x34, 0x33, 0xc6, 0xad, 0x72, 0xc0, 0x29, 0xda, 0x41, 0x2e
};
static const char kRfc5769SampleMsgWithAuthUsername[] =
    "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9";
static const char kRfc5769SampleMsgWithAuthPassword[] = "TheMatrIX";
static const char kRfc5769SampleMsgWithAuthNonce[] =
    "f//499k954d6OL34oL9FSTvy64sA";
static const char kRfc5769SampleMsgWithAuthRealm[] = "example.org";

// 2.1.  Sample Request
static const unsigned char kRfc5769SampleRequest[] = {
  0x00, 0x01, 0x00, 0x58,   //    Request type and message length
  0x21, 0x12, 0xa4, 0x42,   //    Magic cookie
  0xb7, 0xe7, 0xa7, 0x01,   // }
  0xbc, 0x34, 0xd6, 0x86,   // }  Transaction ID
  0xfa, 0x87, 0xdf, 0xae,   // }
  0x80, 0x22, 0x00, 0x10,   //    SOFTWARE attribute header
  0x53, 0x54, 0x55, 0x4e,   // }
  0x20, 0x74, 0x65, 0x73,   // }  User-agent...
  0x74, 0x20, 0x63, 0x6c,   // }  ...name
  0x69, 0x65, 0x6e, 0x74,   // }
  0x00, 0x24, 0x00, 0x04,   //    PRIORITY attribute header
  0x6e, 0x00, 0x01, 0xff,   //    ICE priority value
  0x80, 0x29, 0x00, 0x08,   //    ICE-CONTROLLED attribute header
  0x93, 0x2f, 0xf9, 0xb1,   // }  Pseudo-random tie breaker...
  0x51, 0x26, 0x3b, 0x36,   // }   ...for ICE control
  0x00, 0x06, 0x00, 0x09,   //    USERNAME attribute header
  0x65, 0x76, 0x74, 0x6a,   // }
  0x3a, 0x68, 0x36, 0x76,   // }  Username (9 bytes) and padding (3 bytes)
  0x59, 0x20, 0x20, 0x20,   // }
  0x00, 0x08, 0x00, 0x14,   //    MESSAGE-INTEGRITY attribute header
  0x9a, 0xea, 0xa7, 0x0c,   // }
  0xbf, 0xd8, 0xcb, 0x56,   // }
  0x78, 0x1e, 0xf2, 0xb5,   // }  HMAC-SHA1 fingerprint
  0xb2, 0xd3, 0xf2, 0x49,   // }
  0xc1, 0xb5, 0x71, 0xa2,   // }
  0x80, 0x28, 0x00, 0x04,   //    FINGERPRINT attribute header
  0xe5, 0x7a, 0x3b, 0xcf    //    CRC32 fingerprint
};

// 2.2.  Sample IPv4 Response
static const unsigned char kRfc5769SampleResponse[] = {
  0x01, 0x01, 0x00, 0x3c,  //     Response type and message length
  0x21, 0x12, 0xa4, 0x42,  //     Magic cookie
  0xb7, 0xe7, 0xa7, 0x01,  // }
  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
  0xfa, 0x87, 0xdf, 0xae,  // }
  0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
  0x74, 0x65, 0x73, 0x74,  // }
  0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
  0x74, 0x6f, 0x72, 0x20,  // }
  0x00, 0x20, 0x00, 0x08,  //    XOR-MAPPED-ADDRESS attribute header
  0x00, 0x01, 0xa1, 0x47,  //    Address family (IPv4) and xor'd mapped port
  0xe1, 0x12, 0xa6, 0x43,  //    Xor'd mapped IPv4 address
  0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
  0x2b, 0x91, 0xf5, 0x99,  // }
  0xfd, 0x9e, 0x90, 0xc3,  // }
  0x8c, 0x74, 0x89, 0xf9,  // }  HMAC-SHA1 fingerprint
  0x2a, 0xf9, 0xba, 0x53,  // }
  0xf0, 0x6b, 0xe7, 0xd7,  // }
  0x80, 0x28, 0x00, 0x04,  //    FINGERPRINT attribute header
  0xc0, 0x7d, 0x4c, 0x96   //    CRC32 fingerprint
};

// 2.3.  Sample IPv6 Response
static const unsigned char kRfc5769SampleResponseIPv6[] = {
  0x01, 0x01, 0x00, 0x48,  //    Response type and message length
  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
  0xb7, 0xe7, 0xa7, 0x01,  // }
  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
  0xfa, 0x87, 0xdf, 0xae,  // }
  0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
  0x74, 0x65, 0x73, 0x74,  // }
  0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
  0x74, 0x6f, 0x72, 0x20,  // }
  0x00, 0x20, 0x00, 0x14,  //    XOR-MAPPED-ADDRESS attribute header
  0x00, 0x02, 0xa1, 0x47,  //    Address family (IPv6) and xor'd mapped port.
  0x01, 0x13, 0xa9, 0xfa,  // }
  0xa5, 0xd3, 0xf1, 0x79,  // }  Xor'd mapped IPv6 address
  0xbc, 0x25, 0xf4, 0xb5,  // }
  0xbe, 0xd2, 0xb9, 0xd9,  // }
  0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
  0xa3, 0x82, 0x95, 0x4e,  // }
  0x4b, 0xe6, 0x7b, 0xf1,  // }
  0x17, 0x84, 0xc9, 0x7c,  // }  HMAC-SHA1 fingerprint
  0x82, 0x92, 0xc2, 0x75,  // }
  0xbf, 0xe3, 0xed, 0x41,  // }
  0x80, 0x28, 0x00, 0x04,  //    FINGERPRINT attribute header
  0xc8, 0xfb, 0x0b, 0x4c   //    CRC32 fingerprint
};

// 2.4.  Sample Request with Long-Term Authentication
static const unsigned char kRfc5769SampleRequestLongTermAuth[] = {
  0x00, 0x01, 0x00, 0x60,  //    Request type and message length
  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
  0x78, 0xad, 0x34, 0x33,  // }
  0xc6, 0xad, 0x72, 0xc0,  // }  Transaction ID
  0x29, 0xda, 0x41, 0x2e,  // }
  0x00, 0x06, 0x00, 0x12,  //    USERNAME attribute header
  0xe3, 0x83, 0x9e, 0xe3,  // }
  0x83, 0x88, 0xe3, 0x83,  // }
  0xaa, 0xe3, 0x83, 0x83,  // }  Username value (18 bytes) and padding (2 bytes)
  0xe3, 0x82, 0xaf, 0xe3,  // }
  0x82, 0xb9, 0x00, 0x00,  // }
  0x00, 0x15, 0x00, 0x1c,  //    NONCE attribute header
  0x66, 0x2f, 0x2f, 0x34,  // }
  0x39, 0x39, 0x6b, 0x39,  // }
  0x35, 0x34, 0x64, 0x36,  // }
  0x4f, 0x4c, 0x33, 0x34,  // }  Nonce value
  0x6f, 0x4c, 0x39, 0x46,  // }
  0x53, 0x54, 0x76, 0x79,  // }
  0x36, 0x34, 0x73, 0x41,  // }
  0x00, 0x14, 0x00, 0x0b,  //    REALM attribute header
  0x65, 0x78, 0x61, 0x6d,  // }
  0x70, 0x6c, 0x65, 0x2e,  // }  Realm value (11 bytes) and padding (1 byte)
  0x6f, 0x72, 0x67, 0x00,  // }
  0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
  0xf6, 0x70, 0x24, 0x65,  // }
  0x6d, 0xd6, 0x4a, 0x3e,  // }
  0x02, 0xb8, 0xe0, 0x71,  // }  HMAC-SHA1 fingerprint
  0x2e, 0x85, 0xc9, 0xa2,  // }
  0x8c, 0xa8, 0x96, 0x66   // }
};

// Length parameter is changed to 0x38 from 0x58.
// AddMessageIntegrity will add MI information and update the length param
// accordingly.
static const unsigned char kRfc5769SampleRequestWithoutMI[] = {
  0x00, 0x01, 0x00, 0x38,  //    Request type and message length
  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
  0xb7, 0xe7, 0xa7, 0x01,  // }
  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
  0xfa, 0x87, 0xdf, 0xae,  // }
  0x80, 0x22, 0x00, 0x10,  //    SOFTWARE attribute header
  0x53, 0x54, 0x55, 0x4e,  // }
  0x20, 0x74, 0x65, 0x73,  // }  User-agent...
  0x74, 0x20, 0x63, 0x6c,  // }  ...name
  0x69, 0x65, 0x6e, 0x74,  // }
  0x00, 0x24, 0x00, 0x04,  //    PRIORITY attribute header
  0x6e, 0x00, 0x01, 0xff,  //    ICE priority value
  0x80, 0x29, 0x00, 0x08,  //    ICE-CONTROLLED attribute header
  0x93, 0x2f, 0xf9, 0xb1,  // }  Pseudo-random tie breaker...
  0x51, 0x26, 0x3b, 0x36,  // }   ...for ICE control
  0x00, 0x06, 0x00, 0x09,  //    USERNAME attribute header
  0x65, 0x76, 0x74, 0x6a,  // }
  0x3a, 0x68, 0x36, 0x76,  // }  Username (9 bytes) and padding (3 bytes)
  0x59, 0x20, 0x20, 0x20   // }
};

// This HMAC differs from the RFC 5769 SampleRequest message. This differs
// because spec uses 0x20 for the padding where as our implementation uses 0.
static const unsigned char kCalculatedHmac1[] = {
  0x79, 0x07, 0xc2, 0xd2,  // }
  0xed, 0xbf, 0xea, 0x48,  // }
  0x0e, 0x4c, 0x76, 0xd8,  // }  HMAC-SHA1 fingerprint
  0x29, 0x62, 0xd5, 0xc3,  // }
  0x74, 0x2a, 0xf9, 0xe3   // }
};

// Length parameter is changed to 0x1c from 0x3c.
// AddMessageIntegrity will add MI information and update the length param
// accordingly.
static const unsigned char kRfc5769SampleResponseWithoutMI[] = {
  0x01, 0x01, 0x00, 0x1c,  //    Response type and message length
  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
  0xb7, 0xe7, 0xa7, 0x01,  // }
  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
  0xfa, 0x87, 0xdf, 0xae,  // }
  0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
  0x74, 0x65, 0x73, 0x74,  // }
  0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
  0x74, 0x6f, 0x72, 0x20,  // }
  0x00, 0x20, 0x00, 0x08,  //    XOR-MAPPED-ADDRESS attribute header
  0x00, 0x01, 0xa1, 0x47,  //    Address family (IPv4) and xor'd mapped port
  0xe1, 0x12, 0xa6, 0x43   //    Xor'd mapped IPv4 address
};

// This HMAC differs from the RFC 5769 SampleResponse message. This differs
// because spec uses 0x20 for the padding where as our implementation uses 0.
static const unsigned char kCalculatedHmac2[] = {
  0x5d, 0x6b, 0x58, 0xbe,  // }
  0xad, 0x94, 0xe0, 0x7e,  // }
  0xef, 0x0d, 0xfc, 0x12,  // }  HMAC-SHA1 fingerprint
  0x82, 0xa2, 0xbd, 0x08,  // }
  0x43, 0x14, 0x10, 0x28   // }
};

// A transaction ID without the 'magic cookie' portion
// pjnat's test programs use this transaction ID a lot.
const unsigned char kTestTransactionId1[] = { 0x029, 0x01f, 0x0cd, 0x07c,
                                              0x0ba, 0x058, 0x0ab, 0x0d7,
                                              0x0f2, 0x041, 0x001, 0x000 };

// They use this one sometimes too.
const unsigned char kTestTransactionId2[] = { 0x0e3, 0x0a9, 0x046, 0x0e1,
                                              0x07c, 0x000, 0x0c2, 0x062,
                                              0x054, 0x008, 0x001, 0x000 };

const in6_addr kIPv6TestAddress1 = { { { 0x24, 0x01, 0xfa, 0x00,
                                         0x00, 0x04, 0x10, 0x00,
                                         0xbe, 0x30, 0x5b, 0xff,
                                         0xfe, 0xe5, 0x00, 0xc3 } } };
const in6_addr kIPv6TestAddress2 = { { { 0x24, 0x01, 0xfa, 0x00,
                                         0x00, 0x04, 0x10, 0x12,
                                         0x06, 0x0c, 0xce, 0xff,
                                         0xfe, 0x1f, 0x61, 0xa4 } } };

#ifdef WEBRTC_POSIX
const in_addr kIPv4TestAddress1 =  { 0xe64417ac };
#elif defined WEBRTC_WIN
// Windows in_addr has a union with a uchar[] array first.
const in_addr kIPv4TestAddress1 =  { { 0x0ac, 0x017, 0x044, 0x0e6 } };
#endif
const char kTestUserName1[] = "abcdefgh";
const char kTestUserName2[] = "abc";
const char kTestErrorReason[] = "Unauthorized";
const char kTestOrigin[] = "http://example.com";
const int kTestErrorClass = 4;
const int kTestErrorNumber = 1;
const int kTestErrorCode = 401;

const int kTestMessagePort1 = 59977;
const int kTestMessagePort2 = 47233;
const int kTestMessagePort3 = 56743;
const int kTestMessagePort4 = 40444;

#define ReadStunMessage(X, Y) ReadStunMessageTestCase(X, Y, sizeof(Y));

// Test that the GetStun*Type and IsStun*Type methods work as expected.
TEST_F(StunTest, MessageTypes) {
  EXPECT_EQ(STUN_BINDING_RESPONSE,
      GetStunSuccessResponseType(STUN_BINDING_REQUEST));
  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE,
      GetStunErrorResponseType(STUN_BINDING_REQUEST));
  EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_INDICATION));
  EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_RESPONSE));
  EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_ERROR_RESPONSE));
  EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_INDICATION));
  EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_RESPONSE));
  EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_ERROR_RESPONSE));

  int types[] = {
    STUN_BINDING_REQUEST, STUN_BINDING_INDICATION,
    STUN_BINDING_RESPONSE, STUN_BINDING_ERROR_RESPONSE
  };
  for (size_t i = 0; i < arraysize(types); ++i) {
    EXPECT_EQ(i == 0U, IsStunRequestType(types[i]));
    EXPECT_EQ(i == 1U, IsStunIndicationType(types[i]));
    EXPECT_EQ(i == 2U, IsStunSuccessResponseType(types[i]));
    EXPECT_EQ(i == 3U, IsStunErrorResponseType(types[i]));
    EXPECT_EQ(1, types[i] & 0xFEEF);
  }
}

TEST_F(StunTest, ReadMessageWithIPv4AddressAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4MappedAddress);
  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
  rtc::IPAddress test_address(kIPv4TestAddress1);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
                            kTestMessagePort4, test_address);
}

TEST_F(StunTest, ReadMessageWithIPv4XorAddressAttribute) {
  StunMessage msg;
  StunMessage msg2;
  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  const StunAddressAttribute* addr =
      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  rtc::IPAddress test_address(kIPv4TestAddress1);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
                            kTestMessagePort3, test_address);
}

TEST_F(StunTest, ReadMessageWithIPv6AddressAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  rtc::IPAddress test_address(kIPv6TestAddress1);

  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
                            kTestMessagePort2, test_address);
}

TEST_F(StunTest, ReadMessageWithInvalidAddressAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  rtc::IPAddress test_address(kIPv6TestAddress1);

  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
                            kTestMessagePort2, test_address);
}

TEST_F(StunTest, ReadMessageWithIPv6XorAddressAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);

  rtc::IPAddress test_address(kIPv6TestAddress1);

  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);

  const StunAddressAttribute* addr =
      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
                            kTestMessagePort1, test_address);
}

// Read the RFC5389 fields from the RFC5769 sample STUN request.
TEST_F(StunTest, ReadRfc5769RequestMessage) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kRfc5769SampleRequest);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
                         kStunTransactionIdLength);

  const StunByteStringAttribute* software =
      msg.GetByteString(STUN_ATTR_SOFTWARE);
  ASSERT_TRUE(software != NULL);
  EXPECT_EQ(kRfc5769SampleMsgClientSoftware, software->GetString());

  const StunByteStringAttribute* username =
      msg.GetByteString(STUN_ATTR_USERNAME);
  ASSERT_TRUE(username != NULL);
  EXPECT_EQ(kRfc5769SampleMsgUsername, username->GetString());

  // Actual M-I value checked in a later test.
  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);

  // Fingerprint checked in a later test, but double-check the value here.
  const StunUInt32Attribute* fingerprint =
      msg.GetUInt32(STUN_ATTR_FINGERPRINT);
  ASSERT_TRUE(fingerprint != NULL);
  EXPECT_EQ(0xe57a3bcf, fingerprint->value());
}

// Read the RFC5389 fields from the RFC5769 sample STUN response.
TEST_F(StunTest, ReadRfc5769ResponseMessage) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kRfc5769SampleResponse);
  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
                         kStunTransactionIdLength);

  const StunByteStringAttribute* software =
      msg.GetByteString(STUN_ATTR_SOFTWARE);
  ASSERT_TRUE(software != NULL);
  EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->GetString());

  const StunAddressAttribute* mapped_address =
      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  ASSERT_TRUE(mapped_address != NULL);
  EXPECT_EQ(kRfc5769SampleMsgMappedAddress, mapped_address->GetAddress());

  // Actual M-I and fingerprint checked in later tests.
  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
  ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
}

// Read the RFC5389 fields from the RFC5769 sample STUN response for IPv6.
TEST_F(StunTest, ReadRfc5769ResponseMessageIPv6) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kRfc5769SampleResponseIPv6);
  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
                         kStunTransactionIdLength);

  const StunByteStringAttribute* software =
      msg.GetByteString(STUN_ATTR_SOFTWARE);
  ASSERT_TRUE(software != NULL);
  EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->GetString());

  const StunAddressAttribute* mapped_address =
      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  ASSERT_TRUE(mapped_address != NULL);
  EXPECT_EQ(kRfc5769SampleMsgIPv6MappedAddress, mapped_address->GetAddress());

  // Actual M-I and fingerprint checked in later tests.
  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
  ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
}

// Read the RFC5389 fields from the RFC5769 sample STUN response with auth.
TEST_F(StunTest, ReadRfc5769RequestMessageLongTermAuth) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kRfc5769SampleRequestLongTermAuth);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  CheckStunTransactionID(msg, kRfc5769SampleMsgWithAuthTransactionId,
                         kStunTransactionIdLength);

  const StunByteStringAttribute* username =
      msg.GetByteString(STUN_ATTR_USERNAME);
  ASSERT_TRUE(username != NULL);
  EXPECT_EQ(kRfc5769SampleMsgWithAuthUsername, username->GetString());

  const StunByteStringAttribute* nonce =
      msg.GetByteString(STUN_ATTR_NONCE);
  ASSERT_TRUE(nonce != NULL);
  EXPECT_EQ(kRfc5769SampleMsgWithAuthNonce, nonce->GetString());

  const StunByteStringAttribute* realm =
      msg.GetByteString(STUN_ATTR_REALM);
  ASSERT_TRUE(realm != NULL);
  EXPECT_EQ(kRfc5769SampleMsgWithAuthRealm, realm->GetString());

  // No fingerprint, actual M-I checked in later tests.
  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
  ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) == NULL);
}

// The RFC3489 packet in this test is the same as
// kStunMessageWithIPv4MappedAddress, but with a different value where the
// magic cookie was.
TEST_F(StunTest, ReadLegacyMessage) {
  unsigned char rfc3489_packet[sizeof(kStunMessageWithIPv4MappedAddress)];
  memcpy(rfc3489_packet, kStunMessageWithIPv4MappedAddress,
      sizeof(kStunMessageWithIPv4MappedAddress));
  // Overwrite the magic cookie here.
  memcpy(&rfc3489_packet[4], "ABCD", 4);

  StunMessage msg;
  size_t size = ReadStunMessage(&msg, rfc3489_packet);
  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, &rfc3489_packet[4], kStunTransactionIdLength + 4);

  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
  rtc::IPAddress test_address(kIPv4TestAddress1);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
                            kTestMessagePort4, test_address);
}

TEST_F(StunTest, SetIPv6XorAddressAttributeOwner) {
  StunMessage msg;
  StunMessage msg2;
  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);

  rtc::IPAddress test_address(kIPv6TestAddress1);

  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);

  const StunAddressAttribute* addr =
      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
                            kTestMessagePort1, test_address);

  // Owner with a different transaction ID.
  msg2.SetTransactionID("ABCDABCDABCD");
  StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL);
  addr2.SetIP(addr->ipaddr());
  addr2.SetPort(addr->port());
  addr2.SetOwner(&msg2);
  // The internal IP address shouldn't change.
  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());

  rtc::ByteBufferWriter correct_buf;
  rtc::ByteBufferWriter wrong_buf;
  EXPECT_TRUE(addr->Write(&correct_buf));
  EXPECT_TRUE(addr2.Write(&wrong_buf));
  // But when written out, the buffers should look different.
  ASSERT_NE(0,
            memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
  // And when reading a known good value, the address should be wrong.
  rtc::ByteBufferReader read_buf(correct_buf);
  addr2.Read(&read_buf);
  ASSERT_NE(addr->ipaddr(), addr2.ipaddr());
  addr2.SetIP(addr->ipaddr());
  addr2.SetPort(addr->port());
  // Try writing with no owner at all, should fail and write nothing.
  addr2.SetOwner(NULL);
  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
  wrong_buf.Clear();
  EXPECT_FALSE(addr2.Write(&wrong_buf));
  ASSERT_EQ(0U, wrong_buf.Length());
}

TEST_F(StunTest, SetIPv4XorAddressAttributeOwner) {
  // Unlike the IPv6XorAddressAttributeOwner test, IPv4 XOR address attributes
  // should _not_ be affected by a change in owner. IPv4 XOR address uses the
  // magic cookie value which is fixed.
  StunMessage msg;
  StunMessage msg2;
  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);

  rtc::IPAddress test_address(kIPv4TestAddress1);

  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  const StunAddressAttribute* addr =
      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
                            kTestMessagePort3, test_address);

  // Owner with a different transaction ID.
  msg2.SetTransactionID("ABCDABCDABCD");
  StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL);
  addr2.SetIP(addr->ipaddr());
  addr2.SetPort(addr->port());
  addr2.SetOwner(&msg2);
  // The internal IP address shouldn't change.
  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());

  rtc::ByteBufferWriter correct_buf;
  rtc::ByteBufferWriter wrong_buf;
  EXPECT_TRUE(addr->Write(&correct_buf));
  EXPECT_TRUE(addr2.Write(&wrong_buf));
  // The same address data should be written.
  ASSERT_EQ(0,
            memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
  // And an attribute should be able to un-XOR an address belonging to a message
  // with a different transaction ID.
  rtc::ByteBufferReader read_buf(correct_buf);
  EXPECT_TRUE(addr2.Read(&read_buf));
  ASSERT_EQ(addr->ipaddr(), addr2.ipaddr());

  // However, no owner is still an error, should fail and write nothing.
  addr2.SetOwner(NULL);
  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
  wrong_buf.Clear();
  EXPECT_FALSE(addr2.Write(&wrong_buf));
}

TEST_F(StunTest, CreateIPv6AddressAttribute) {
  rtc::IPAddress test_ip(kIPv6TestAddress2);

  StunAddressAttribute* addr =
      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
  rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
  addr->SetAddress(test_addr);

  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
                            kTestMessagePort2, test_ip);
  delete addr;
}

TEST_F(StunTest, CreateIPv4AddressAttribute) {
  struct in_addr test_in_addr;
  test_in_addr.s_addr = 0xBEB0B0BE;
  rtc::IPAddress test_ip(test_in_addr);

  StunAddressAttribute* addr =
      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
  rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
  addr->SetAddress(test_addr);

  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
                            kTestMessagePort2, test_ip);
  delete addr;
}

// Test that we don't care what order we set the parts of an address
TEST_F(StunTest, CreateAddressInArbitraryOrder) {
  StunAddressAttribute* addr =
  StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
  // Port first
  addr->SetPort(kTestMessagePort1);
  addr->SetIP(rtc::IPAddress(kIPv4TestAddress1));
  ASSERT_EQ(kTestMessagePort1, addr->port());
  ASSERT_EQ(rtc::IPAddress(kIPv4TestAddress1), addr->ipaddr());

  StunAddressAttribute* addr2 =
  StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
  // IP first
  addr2->SetIP(rtc::IPAddress(kIPv4TestAddress1));
  addr2->SetPort(kTestMessagePort2);
  ASSERT_EQ(kTestMessagePort2, addr2->port());
  ASSERT_EQ(rtc::IPAddress(kIPv4TestAddress1), addr2->ipaddr());

  delete addr;
  delete addr2;
}

TEST_F(StunTest, WriteMessageWithIPv6AddressAttribute) {
  StunMessage msg;
  size_t size = sizeof(kStunMessageWithIPv6MappedAddress);

  rtc::IPAddress test_ip(kIPv6TestAddress1);

  msg.SetType(STUN_BINDING_REQUEST);
  msg.SetTransactionID(
      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
                  kStunTransactionIdLength));
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  StunAddressAttribute* addr =
      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
  rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
  addr->SetAddress(test_addr);
  EXPECT_TRUE(msg.AddAttribute(addr));

  CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6MappedAddress));
  int len1 = static_cast<int>(out.Length());
  rtc::ByteBufferReader read_buf(out);
  std::string bytes;
  read_buf.ReadString(&bytes, len1);
  ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv6MappedAddress, len1));
}

TEST_F(StunTest, WriteMessageWithIPv4AddressAttribute) {
  StunMessage msg;
  size_t size = sizeof(kStunMessageWithIPv4MappedAddress);

  rtc::IPAddress test_ip(kIPv4TestAddress1);

  msg.SetType(STUN_BINDING_RESPONSE);
  msg.SetTransactionID(
      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
                  kStunTransactionIdLength));
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  StunAddressAttribute* addr =
      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
  rtc::SocketAddress test_addr(test_ip, kTestMessagePort4);
  addr->SetAddress(test_addr);
  EXPECT_TRUE(msg.AddAttribute(addr));

  CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4MappedAddress));
  int len1 = static_cast<int>(out.Length());
  rtc::ByteBufferReader read_buf(out);
  std::string bytes;
  read_buf.ReadString(&bytes, len1);
  ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv4MappedAddress, len1));
}

TEST_F(StunTest, WriteMessageWithIPv6XorAddressAttribute) {
  StunMessage msg;
  size_t size = sizeof(kStunMessageWithIPv6XorMappedAddress);

  rtc::IPAddress test_ip(kIPv6TestAddress1);

  msg.SetType(STUN_BINDING_RESPONSE);
  msg.SetTransactionID(
      std::string(reinterpret_cast<const char*>(kTestTransactionId2),
                  kStunTransactionIdLength));
  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);

  StunAddressAttribute* addr =
      StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  rtc::SocketAddress test_addr(test_ip, kTestMessagePort1);
  addr->SetAddress(test_addr);
  EXPECT_TRUE(msg.AddAttribute(addr));

  CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6XorMappedAddress));
  int len1 = static_cast<int>(out.Length());
  rtc::ByteBufferReader read_buf(out);
  std::string bytes;
  read_buf.ReadString(&bytes, len1);
  ASSERT_EQ(0,
            memcmp(bytes.c_str(), kStunMessageWithIPv6XorMappedAddress, len1));
}

TEST_F(StunTest, WriteMessageWithIPv4XoreAddressAttribute) {
  StunMessage msg;
  size_t size = sizeof(kStunMessageWithIPv4XorMappedAddress);

  rtc::IPAddress test_ip(kIPv4TestAddress1);

  msg.SetType(STUN_BINDING_RESPONSE);
  msg.SetTransactionID(
      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
                  kStunTransactionIdLength));
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);

  StunAddressAttribute* addr =
      StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  rtc::SocketAddress test_addr(test_ip, kTestMessagePort3);
  addr->SetAddress(test_addr);
  EXPECT_TRUE(msg.AddAttribute(addr));

  CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4XorMappedAddress));
  int len1 = static_cast<int>(out.Length());
  rtc::ByteBufferReader read_buf(out);
  std::string bytes;
  read_buf.ReadString(&bytes, len1);
  ASSERT_EQ(0,
            memcmp(bytes.c_str(), kStunMessageWithIPv4XorMappedAddress, len1));
}

TEST_F(StunTest, ReadByteStringAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithByteStringAttribute);

  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
  const StunByteStringAttribute* username =
      msg.GetByteString(STUN_ATTR_USERNAME);
  ASSERT_TRUE(username != NULL);
  EXPECT_EQ(kTestUserName1, username->GetString());
}

TEST_F(StunTest, ReadPaddedByteStringAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg,
                                kStunMessageWithPaddedByteStringAttribute);
  ASSERT_NE(0U, size);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
  const StunByteStringAttribute* username =
      msg.GetByteString(STUN_ATTR_USERNAME);
  ASSERT_TRUE(username != NULL);
  EXPECT_EQ(kTestUserName2, username->GetString());
}

TEST_F(StunTest, ReadErrorCodeAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithErrorAttribute);

  CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, size);
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
  const StunErrorCodeAttribute* errorcode = msg.GetErrorCode();
  ASSERT_TRUE(errorcode != NULL);
  EXPECT_EQ(kTestErrorClass, errorcode->eclass());
  EXPECT_EQ(kTestErrorNumber, errorcode->number());
  EXPECT_EQ(kTestErrorReason, errorcode->reason());
  EXPECT_EQ(kTestErrorCode, errorcode->code());
}

TEST_F(StunTest, ReadMessageWithAUInt16ListAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithUInt16ListAttribute);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  const StunUInt16ListAttribute* types = msg.GetUnknownAttributes();
  ASSERT_TRUE(types != NULL);
  EXPECT_EQ(3U, types->Size());
  EXPECT_EQ(0x1U, types->GetType(0));
  EXPECT_EQ(0x1000U, types->GetType(1));
  EXPECT_EQ(0xAB0CU, types->GetType(2));
}

TEST_F(StunTest, ReadMessageWithAnUnknownAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithUnknownAttribute);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);

  // Parsing should have succeeded and there should be a USERNAME attribute
  const StunByteStringAttribute* username =
      msg.GetByteString(STUN_ATTR_USERNAME);
  ASSERT_TRUE(username != NULL);
  EXPECT_EQ(kTestUserName2, username->GetString());
}

TEST_F(StunTest, ReadMessageWithOriginAttribute) {
  StunMessage msg;
  size_t size = ReadStunMessage(&msg, kStunMessageWithOriginAttribute);
  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
  const StunByteStringAttribute* origin =
      msg.GetByteString(STUN_ATTR_ORIGIN);
  ASSERT_TRUE(origin != NULL);
  EXPECT_EQ(kTestOrigin, origin->GetString());
}

TEST_F(StunTest, WriteMessageWithAnErrorCodeAttribute) {
  StunMessage msg;
  size_t size = sizeof(kStunMessageWithErrorAttribute);

  msg.SetType(STUN_BINDING_ERROR_RESPONSE);
  msg.SetTransactionID(
      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
                  kStunTransactionIdLength));
  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
  StunErrorCodeAttribute* errorcode = StunAttribute::CreateErrorCode();
  errorcode->SetCode(kTestErrorCode);
  errorcode->SetReason(kTestErrorReason);
  EXPECT_TRUE(msg.AddAttribute(errorcode));
  CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, (size - 20));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  ASSERT_EQ(size, out.Length());
  // No padding.
  ASSERT_EQ(0, memcmp(out.Data(), kStunMessageWithErrorAttribute, size));
}

TEST_F(StunTest, WriteMessageWithAUInt16ListAttribute) {
  StunMessage msg;
  size_t size = sizeof(kStunMessageWithUInt16ListAttribute);

  msg.SetType(STUN_BINDING_REQUEST);
  msg.SetTransactionID(
      std::string(reinterpret_cast<const char*>(kTestTransactionId2),
                  kStunTransactionIdLength));
  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
  StunUInt16ListAttribute* list = StunAttribute::CreateUnknownAttributes();
  list->AddType(0x1U);
  list->AddType(0x1000U);
  list->AddType(0xAB0CU);
  EXPECT_TRUE(msg.AddAttribute(list));
  CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  ASSERT_EQ(size, out.Length());
  // Check everything up to the padding.
  ASSERT_EQ(0,
            memcmp(out.Data(), kStunMessageWithUInt16ListAttribute, size - 2));
}

TEST_F(StunTest, WriteMessageWithOriginAttribute) {
  StunMessage msg;
  size_t size = sizeof(kStunMessageWithOriginAttribute);

  msg.SetType(STUN_BINDING_REQUEST);
  msg.SetTransactionID(
      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
                  kStunTransactionIdLength));
  StunByteStringAttribute* origin =
      new StunByteStringAttribute(STUN_ATTR_ORIGIN, kTestOrigin);
  EXPECT_TRUE(msg.AddAttribute(origin));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  ASSERT_EQ(size, out.Length());
  // Check everything up to the padding
  ASSERT_EQ(0, memcmp(out.Data(), kStunMessageWithOriginAttribute, size - 2));
}

// Test that we fail to read messages with invalid lengths.
void CheckFailureToRead(const unsigned char* testcase, size_t length) {
  StunMessage msg;
  const char* input = reinterpret_cast<const char*>(testcase);
  rtc::ByteBufferReader buf(input, length);
  ASSERT_FALSE(msg.Read(&buf));
}

TEST_F(StunTest, FailToReadInvalidMessages) {
  CheckFailureToRead(kStunMessageWithZeroLength,
                     kRealLengthOfInvalidLengthTestCases);
  CheckFailureToRead(kStunMessageWithSmallLength,
                     kRealLengthOfInvalidLengthTestCases);
  CheckFailureToRead(kStunMessageWithExcessLength,
                     kRealLengthOfInvalidLengthTestCases);
}

// Test that we properly fail to read a non-STUN message.
TEST_F(StunTest, FailToReadRtcpPacket) {
  CheckFailureToRead(kRtcpPacket, sizeof(kRtcpPacket));
}

// Check our STUN message validation code against the RFC5769 test messages.
TEST_F(StunTest, ValidateMessageIntegrity) {
  // Try the messages from RFC 5769.
  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleRequest),
      sizeof(kRfc5769SampleRequest),
      kRfc5769SampleMsgPassword));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleRequest),
      sizeof(kRfc5769SampleRequest),
      "InvalidPassword"));

  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleResponse),
      sizeof(kRfc5769SampleResponse),
      kRfc5769SampleMsgPassword));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleResponse),
      sizeof(kRfc5769SampleResponse),
      "InvalidPassword"));

  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
      sizeof(kRfc5769SampleResponseIPv6),
      kRfc5769SampleMsgPassword));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
      sizeof(kRfc5769SampleResponseIPv6),
      "InvalidPassword"));

  // We first need to compute the key for the long-term authentication HMAC.
  std::string key;
  ComputeStunCredentialHash(kRfc5769SampleMsgWithAuthUsername,
      kRfc5769SampleMsgWithAuthRealm, kRfc5769SampleMsgWithAuthPassword, &key);
  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
      sizeof(kRfc5769SampleRequestLongTermAuth), key));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
      sizeof(kRfc5769SampleRequestLongTermAuth),
      "InvalidPassword"));

  // Try some edge cases.
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
      sizeof(kStunMessageWithZeroLength),
      kRfc5769SampleMsgPassword));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
      sizeof(kStunMessageWithExcessLength),
      kRfc5769SampleMsgPassword));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
      sizeof(kStunMessageWithSmallLength),
      kRfc5769SampleMsgPassword));

  // Again, but with the lengths matching what is claimed in the headers.
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
      kStunHeaderSize + rtc::GetBE16(&kStunMessageWithZeroLength[2]),
      kRfc5769SampleMsgPassword));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
      kStunHeaderSize + rtc::GetBE16(&kStunMessageWithExcessLength[2]),
      kRfc5769SampleMsgPassword));
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
      kStunHeaderSize + rtc::GetBE16(&kStunMessageWithSmallLength[2]),
      kRfc5769SampleMsgPassword));

  // Check that a too-short HMAC doesn't cause buffer overflow.
  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
      reinterpret_cast<const char*>(kStunMessageWithBadHmacAtEnd),
      sizeof(kStunMessageWithBadHmacAtEnd),
      kRfc5769SampleMsgPassword));

  // Test that munging a single bit anywhere in the message causes the
  // message-integrity check to fail, unless it is after the M-I attribute.
  char buf[sizeof(kRfc5769SampleRequest)];
  memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
  for (size_t i = 0; i < sizeof(buf); ++i) {
    buf[i] ^= 0x01;
    if (i > 0)
      buf[i - 1] ^= 0x01;
    EXPECT_EQ(i >= sizeof(buf) - 8, StunMessage::ValidateMessageIntegrity(
        buf, sizeof(buf), kRfc5769SampleMsgPassword));
  }
}

// Validate that we generate correct MESSAGE-INTEGRITY attributes.
// Note the use of IceMessage instead of StunMessage; this is necessary because
// the RFC5769 test messages used include attributes not found in basic STUN.
TEST_F(StunTest, AddMessageIntegrity) {
  IceMessage msg;
  rtc::ByteBufferReader buf(
      reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
      sizeof(kRfc5769SampleRequestWithoutMI));
  EXPECT_TRUE(msg.Read(&buf));
  EXPECT_TRUE(msg.AddMessageIntegrity(kRfc5769SampleMsgPassword));
  const StunByteStringAttribute* mi_attr =
      msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
  EXPECT_EQ(20U, mi_attr->length());
  EXPECT_EQ(0, memcmp(
      mi_attr->bytes(), kCalculatedHmac1, sizeof(kCalculatedHmac1)));

  rtc::ByteBufferWriter buf1;
  EXPECT_TRUE(msg.Write(&buf1));
  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
        reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
        kRfc5769SampleMsgPassword));

  IceMessage msg2;
  rtc::ByteBufferReader buf2(
      reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI),
      sizeof(kRfc5769SampleResponseWithoutMI));
  EXPECT_TRUE(msg2.Read(&buf2));
  EXPECT_TRUE(msg2.AddMessageIntegrity(kRfc5769SampleMsgPassword));
  const StunByteStringAttribute* mi_attr2 =
      msg2.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
  EXPECT_EQ(20U, mi_attr2->length());
  EXPECT_EQ(
      0, memcmp(mi_attr2->bytes(), kCalculatedHmac2, sizeof(kCalculatedHmac2)));

  rtc::ByteBufferWriter buf3;
  EXPECT_TRUE(msg2.Write(&buf3));
  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
        reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
        kRfc5769SampleMsgPassword));
}

// Check our STUN message validation code against the RFC5769 test messages.
TEST_F(StunTest, ValidateFingerprint) {
  EXPECT_TRUE(StunMessage::ValidateFingerprint(
      reinterpret_cast<const char*>(kRfc5769SampleRequest),
      sizeof(kRfc5769SampleRequest)));
  EXPECT_TRUE(StunMessage::ValidateFingerprint(
      reinterpret_cast<const char*>(kRfc5769SampleResponse),
      sizeof(kRfc5769SampleResponse)));
  EXPECT_TRUE(StunMessage::ValidateFingerprint(
      reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
      sizeof(kRfc5769SampleResponseIPv6)));

  EXPECT_FALSE(StunMessage::ValidateFingerprint(
      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
      sizeof(kStunMessageWithZeroLength)));
  EXPECT_FALSE(StunMessage::ValidateFingerprint(
      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
      sizeof(kStunMessageWithExcessLength)));
  EXPECT_FALSE(StunMessage::ValidateFingerprint(
      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
      sizeof(kStunMessageWithSmallLength)));

  // Test that munging a single bit anywhere in the message causes the
  // fingerprint check to fail.
  char buf[sizeof(kRfc5769SampleRequest)];
  memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
  for (size_t i = 0; i < sizeof(buf); ++i) {
    buf[i] ^= 0x01;
    if (i > 0)
      buf[i - 1] ^= 0x01;
    EXPECT_FALSE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
  }
  // Put them all back to normal and the check should pass again.
  buf[sizeof(buf) - 1] ^= 0x01;
  EXPECT_TRUE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
}

TEST_F(StunTest, AddFingerprint) {
  IceMessage msg;
  rtc::ByteBufferReader buf(
      reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
      sizeof(kRfc5769SampleRequestWithoutMI));
  EXPECT_TRUE(msg.Read(&buf));
  EXPECT_TRUE(msg.AddFingerprint());

  rtc::ByteBufferWriter buf1;
  EXPECT_TRUE(msg.Write(&buf1));
  EXPECT_TRUE(StunMessage::ValidateFingerprint(
      reinterpret_cast<const char*>(buf1.Data()), buf1.Length()));
}

// Sample "GTURN" relay message.
static const unsigned char kRelayMessage[] = {
  0x00, 0x01, 0x00, 88,    // message header
  0x21, 0x12, 0xA4, 0x42,  // magic cookie
  '0', '1', '2', '3',      // transaction id
  '4', '5', '6', '7',
  '8', '9', 'a', 'b',
  0x00, 0x01, 0x00, 8,     // mapped address
  0x00, 0x01, 0x00, 13,
  0x00, 0x00, 0x00, 17,
  0x00, 0x06, 0x00, 12,    // username
  'a', 'b', 'c', 'd',
  'e', 'f', 'g', 'h',
  'i', 'j', 'k', 'l',
  0x00, 0x0d, 0x00, 4,     // lifetime
  0x00, 0x00, 0x00, 11,
  0x00, 0x0f, 0x00, 4,     // magic cookie
  0x72, 0xc6, 0x4b, 0xc6,
  0x00, 0x10, 0x00, 4,     // bandwidth
  0x00, 0x00, 0x00, 6,
  0x00, 0x11, 0x00, 8,     // destination address
  0x00, 0x01, 0x00, 13,
  0x00, 0x00, 0x00, 17,
  0x00, 0x12, 0x00, 8,     // source address 2
  0x00, 0x01, 0x00, 13,
  0x00, 0x00, 0x00, 17,
  0x00, 0x13, 0x00, 7,     // data
  'a', 'b', 'c', 'd',
  'e', 'f', 'g', 0         // DATA must be padded per rfc5766.
};

// Test that we can read the GTURN-specific fields.
TEST_F(StunTest, ReadRelayMessage) {
  RelayMessage msg, msg2;

  const char* input = reinterpret_cast<const char*>(kRelayMessage);
  size_t size = sizeof(kRelayMessage);
  rtc::ByteBufferReader buf(input, size);
  EXPECT_TRUE(msg.Read(&buf));

  EXPECT_EQ(STUN_BINDING_REQUEST, msg.type());
  EXPECT_EQ(size - 20, msg.length());
  EXPECT_EQ("0123456789ab", msg.transaction_id());

  msg2.SetType(STUN_BINDING_REQUEST);
  msg2.SetTransactionID("0123456789ab");

  in_addr legacy_in_addr;
  legacy_in_addr.s_addr = htonl(17U);
  rtc::IPAddress legacy_ip(legacy_in_addr);

  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
  ASSERT_TRUE(addr != NULL);
  EXPECT_EQ(1, addr->family());
  EXPECT_EQ(13, addr->port());
  EXPECT_EQ(legacy_ip, addr->ipaddr());

  StunAddressAttribute* addr2 =
      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
  addr2->SetPort(13);
  addr2->SetIP(legacy_ip);
  EXPECT_TRUE(msg2.AddAttribute(addr2));

  const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME);
  ASSERT_TRUE(bytes != NULL);
  EXPECT_EQ(12U, bytes->length());
  EXPECT_EQ("abcdefghijkl", bytes->GetString());

  StunByteStringAttribute* bytes2 =
  StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
  bytes2->CopyBytes("abcdefghijkl");
  EXPECT_TRUE(msg2.AddAttribute(bytes2));

  const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
  ASSERT_TRUE(uval != NULL);
  EXPECT_EQ(11U, uval->value());

  StunUInt32Attribute* uval2 = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
  uval2->SetValue(11);
  EXPECT_TRUE(msg2.AddAttribute(uval2));

  bytes = msg.GetByteString(STUN_ATTR_MAGIC_COOKIE);
  ASSERT_TRUE(bytes != NULL);
  EXPECT_EQ(4U, bytes->length());
  EXPECT_EQ(0,
            memcmp(bytes->bytes(),
                   TURN_MAGIC_COOKIE_VALUE,
                   sizeof(TURN_MAGIC_COOKIE_VALUE)));

  bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
  bytes2->CopyBytes(reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
                    sizeof(TURN_MAGIC_COOKIE_VALUE));
  EXPECT_TRUE(msg2.AddAttribute(bytes2));

  uval = msg.GetUInt32(STUN_ATTR_BANDWIDTH);
  ASSERT_TRUE(uval != NULL);
  EXPECT_EQ(6U, uval->value());

  uval2 = StunAttribute::CreateUInt32(STUN_ATTR_BANDWIDTH);
  uval2->SetValue(6);
  EXPECT_TRUE(msg2.AddAttribute(uval2));

  addr = msg.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
  ASSERT_TRUE(addr != NULL);
  EXPECT_EQ(1, addr->family());
  EXPECT_EQ(13, addr->port());
  EXPECT_EQ(legacy_ip, addr->ipaddr());

  addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
  addr2->SetPort(13);
  addr2->SetIP(legacy_ip);
  EXPECT_TRUE(msg2.AddAttribute(addr2));

  addr = msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
  ASSERT_TRUE(addr != NULL);
  EXPECT_EQ(1, addr->family());
  EXPECT_EQ(13, addr->port());
  EXPECT_EQ(legacy_ip, addr->ipaddr());

  addr2 = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
  addr2->SetPort(13);
  addr2->SetIP(legacy_ip);
  EXPECT_TRUE(msg2.AddAttribute(addr2));

  bytes = msg.GetByteString(STUN_ATTR_DATA);
  ASSERT_TRUE(bytes != NULL);
  EXPECT_EQ(7U, bytes->length());
  EXPECT_EQ("abcdefg", bytes->GetString());

  bytes2 = StunAttribute::CreateByteString(STUN_ATTR_DATA);
  bytes2->CopyBytes("abcdefg");
  EXPECT_TRUE(msg2.AddAttribute(bytes2));

  rtc::ByteBufferWriter out;
  EXPECT_TRUE(msg.Write(&out));
  EXPECT_EQ(size, out.Length());
  size_t len1 = out.Length();
  rtc::ByteBufferReader read_buf(out);
  std::string outstring;
  read_buf.ReadString(&outstring, len1);
  EXPECT_EQ(0, memcmp(outstring.c_str(), input, len1));

  rtc::ByteBufferWriter out2;
  EXPECT_TRUE(msg2.Write(&out2));
  EXPECT_EQ(size, out2.Length());
  size_t len2 = out2.Length();
  rtc::ByteBufferReader read_buf2(out2);
  std::string outstring2;
  read_buf2.ReadString(&outstring2, len2);
  EXPECT_EQ(0, memcmp(outstring2.c_str(), input, len2));
}

}  // namespace cricket


text:
package org.elasticsearch.xpack.monitoring.exporter.http;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Objects;

/**
 * {@code HttpHostBuilder} creates an {@link HttpHost} meant to be used with an Elasticsearch cluster. The {@code HttpHostBuilder} uses
 * defaults that are most common for Elasticsearch, including an unspecified port defaulting to 9200 and the default scheme
 * being http (as opposed to https).
 *

 * The only required detail is the host to connect too, either via hostname or IP address.
 *

 * This enables you to create an {@code HttpHost} directly via a builder mechanism, or indirectly by parsing a URI-like string. For example:
 *

 * HttpHost host1 = HttpHostBuilder.builder("localhost").build();               // http://localhost:9200
 * HttpHost host2 = HttpHostBuilder.builder("localhost:9200").build();          // http://localhost:9200
 * HttpHost host4 = HttpHostBuilder.builder("http://localhost:9200").build();   // http://localhost:9200
 * HttpHost host5 = HttpHostBuilder.builder("https://localhost:9200").build();  // https://localhost:9200
 * HttpHost host6 = HttpHostBuilder.builder("https://localhost:9200").build();  // https://127.0.0.1:9200 (IPv4 localhost)
 * HttpHost host7 = HttpHostBuilder.builder("http://10.1.2.3").build();         // http://10.2.3.4:9200
 * HttpHost host8 = HttpHostBuilder.builder("https://[::1]").build();           // http://[::1]:9200      (IPv6 localhost)
 * HttpHost host9 = HttpHostBuilder.builder("https://[::1]:9200").build();      // http://[::1]:9200      (IPv6 localhost)
 * HttpHost host10= HttpHostBuilder.builder("https://sub.domain").build();      // https://sub.domain:9200
 *

 * Note: {@code HttpHost}s are the mechanism that the {@link RestClient} uses to build the base request. If you need to specify proxy
 * settings, then use the {@link RestClientBuilder.RequestConfigCallback} to configure the {@code Proxy} settings.
 *
 * @see #builder(String)
 * @see #builder()
 */
public class HttpHostBuilder {

    /**
     * The scheme used to connect to Elasticsearch.
     */
    private Scheme scheme = Scheme.HTTP;
    /**
     * The host is the only required portion of the supplied URI when building it. The rest can be defaulted.
     */
    private String host = null;
    /**
     * The port used to connect to Elasticsearch.
     *

     * The default port is 9200 when unset.
     */
    private int port = -1;

    /**
     * Create an empty {@link HttpHostBuilder}.
     *

     * The expectation is that you then explicitly build the {@link HttpHost} piece-by-piece.
     *

     * For example:
     *

     * HttpHost localhost = HttpHostBuilder.builder().host("localhost").build();                            // http://localhost:9200
     * HttpHost explicitLocalhost = HttpHostBuilder.builder.().scheme(Scheme.HTTP).host("localhost").port(9200).build();
     *                                                                                // http://localhost:9200
     * HttpHost secureLocalhost = HttpHostBuilder.builder().scheme(Scheme.HTTPS).host("localhost").build(); // https://localhost:9200
     * HttpHost differentPort = HttpHostBuilder.builder().host("my_host").port(19200).build();              // https://my_host:19200
     * HttpHost ipBased = HttpHostBuilder.builder().host("192.168.0.11").port(80).build();                  // https://192.168.0.11:80
     *

     *
     * @return Never {@code null}.
     */
    public static HttpHostBuilder builder() {
        return new HttpHostBuilder();
    }

    /**
     * Create an empty {@link HttpHostBuilder}.
     *

     * The expectation is that you then explicitly build the {@link HttpHost} piece-by-piece.
     *

     * For example:
     *

     * HttpHost localhost = HttpHostBuilder.builder("localhost").build();                     // http://localhost:9200
     * HttpHost explicitLocalhost = HttpHostBuilder.builder("http://localhost:9200").build(); // http://localhost:9200
     * HttpHost secureLocalhost = HttpHostBuilder.builder("https://localhost").build();       // https://localhost:9200
     * HttpHost differentPort = HttpHostBuilder.builder("my_host:19200").build();             // http://my_host:19200
     * HttpHost ipBased = HttpHostBuilder.builder("192.168.0.11:80").build();                 // http://192.168.0.11:80
     *

     *
     * @return Never {@code null}.
     * @throws NullPointerException if {@code uri} is {@code null}.
     * @throws IllegalArgumentException if any issue occurs while parsing the {@code uri}.
     */
    public static HttpHostBuilder builder(final String uri) {
        return new HttpHostBuilder(uri);
    }

    /**
     * Create a new {@link HttpHost} from scratch.
     */
    HttpHostBuilder() {
        // everything is in the default state
    }

    /**
     * Create a new {@link HttpHost} based on the supplied host.
     *
     * @param uri The [partial] URI used to build.
     * @throws NullPointerException if {@code uri} is {@code null}.
     * @throws IllegalArgumentException if any issue occurs while parsing the {@code uri}.
     */
    HttpHostBuilder(final String uri) {
        Objects.requireNonNull(uri, "uri must not be null");

        try {
            String cleanedUri = uri;

            if (uri.contains("://") == false) {
                cleanedUri = "http://" + uri;
            }

            final URI parsedUri = new URI(cleanedUri);

            // "localhost:9200" doesn't have a scheme
            if (parsedUri.getScheme() != null) {
                scheme(Scheme.fromString(parsedUri.getScheme()));
            }

            if (parsedUri.getHost() != null) {
                host(parsedUri.getHost());
            } else {
                // if the host is null, then it means one of two things: we're in a broken state _or_ it had something like underscores
                // we want the raw form so that parts of the URI are not decoded
                final String host = parsedUri.getRawAuthority();

                // they explicitly provided the port, which is unparsed when the host is null
                if (host.contains(":")) {
                    final String[] hostPort = host.split(":", 2);

                    host(hostPort[0]);
                    port(Integer.parseInt(hostPort[1]));
                } else {
                    host(host);
                }
            }

            if (parsedUri.getPort() != -1) {
                port(parsedUri.getPort());
            }

            // fail for proxies
            if (parsedUri.getRawPath() != null && parsedUri.getRawPath().isEmpty() == false) {
                throw new IllegalArgumentException(
                    "HttpHosts do not use paths [" + parsedUri.getRawPath() +
                        "]. see setRequestConfigCallback for proxies. value: [" + uri + "]");
            }
        } catch (URISyntaxException | IndexOutOfBoundsException | NullPointerException e) {
            throw new IllegalArgumentException("error parsing host: [" + uri + "]", e);
        }
    }

    /**
     * Set the scheme (aka protocol) for the {@link HttpHost}.
     *
     * @param scheme The scheme to use.
     * @return Always {@code this}.
     * @throws NullPointerException if {@code scheme} is {@code null}.
     */
    public HttpHostBuilder scheme(final Scheme scheme) {
        this.scheme = Objects.requireNonNull(scheme);

        return this;
    }

    /**
     * Set the host for the {@link HttpHost}.
     *

     * This does not attempt to parse the {@code host} in any way.
     *
     * @param host The host to use.
     * @return Always {@code this}.
     * @throws NullPointerException if {@code host} is {@code null}.
     */
    public HttpHostBuilder host(final String host) {
        this.host = Objects.requireNonNull(host);

        return this;
    }

    /**
     * Set the port for the {@link HttpHost}.
     *

     * Specifying the {@code port} as -1 will cause it to be defaulted to 9200 when the {@code HttpHost} is built.
     *
     * @param port The port to use.
     * @return Always {@code this}.
     * @throws IllegalArgumentException if the {@code port} is not -1 or [1, 65535].
     */
    public HttpHostBuilder port(final int port) {
        // setting a port to 0 makes no sense when you're the client; -1 allows us to use the default when we build
        if (port != -1 && (port < 1 || port > 65535)) {
            throw new IllegalArgumentException("port must be -1 for the default or [1, 65535]. was: " + port);
        }

        this.port = port;

        return this;
    }

    /**
     * Create a new {@link HttpHost} from the current {@code scheme}, {@code host}, and {@code port}.
     *
     * @return Never {@code null}.
     * @throws IllegalStateException if {@code host} is unset.
     */
    public HttpHost build() {
        if (host == null) {
            throw new IllegalStateException("host must be set");
        }

        return new HttpHost(host, port == -1 ? 9200 : port, scheme.toString());
    }

}


text:
package uk.gov.gchq.gaffer.rest;

import org.apache.commons.lang.StringUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Stream;

import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_BANNER_COLOUR;
import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_BANNER_DESCRIPTION;
import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_DESCRIPTION;
import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_DESCRIPTION_DEFAULT;
import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_DOCUMENTATION_URL;
import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_DOCUMENTATION_URL_DEFAULT;
import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_TITLE;
import static uk.gov.gchq.gaffer.rest.SystemProperty.APP_TITLE_DEFAULT;
import static uk.gov.gchq.gaffer.rest.SystemProperty.FAVICON_LARGE_URL;
import static uk.gov.gchq.gaffer.rest.SystemProperty.FAVICON_SMALL_URL;
import static uk.gov.gchq.gaffer.rest.SystemProperty.GAFFER_VERSION;
import static uk.gov.gchq.gaffer.rest.SystemProperty.GAFFER_VERSION_DEFAULT;
import static uk.gov.gchq.gaffer.rest.SystemProperty.KORYPHE_VERSION;
import static uk.gov.gchq.gaffer.rest.SystemProperty.KORYPHE_VERSION_DEFAULT;
import static uk.gov.gchq.gaffer.rest.SystemProperty.LOGO_IMAGE_URL;
import static uk.gov.gchq.gaffer.rest.SystemProperty.LOGO_IMAGE_URL_DEFAULT;
import static uk.gov.gchq.gaffer.rest.SystemProperty.LOGO_LINK;
import static uk.gov.gchq.gaffer.rest.SystemProperty.LOGO_LINK_DEFAULT;

/**
 * Utility class used to retrieve the Gaffer System Properties
 */
public final class PropertiesUtil {

    private static final String EXPOSED_PROPERTIES = SystemProperty.EXPOSED_PROPERTIES;
    private static final Map<String, String> CORE_EXPOSED_PROPERTIES = createCoreExposedProperties();

    private static Map<String, String> createCoreExposedProperties() {
        final Map<String, String> map = new LinkedHashMap<>();
        map.put(APP_TITLE, APP_TITLE_DEFAULT);
        map.put(APP_DESCRIPTION, APP_DESCRIPTION_DEFAULT);
        map.put(APP_BANNER_DESCRIPTION, "");
        map.put(APP_BANNER_COLOUR, "");
        map.put(APP_DOCUMENTATION_URL, APP_DOCUMENTATION_URL_DEFAULT);
        map.put(LOGO_LINK, LOGO_LINK_DEFAULT);
        map.put(LOGO_IMAGE_URL, LOGO_IMAGE_URL_DEFAULT);
        map.put(FAVICON_SMALL_URL, LOGO_IMAGE_URL_DEFAULT);
        map.put(FAVICON_LARGE_URL, LOGO_IMAGE_URL_DEFAULT);
        map.put(GAFFER_VERSION, GAFFER_VERSION_DEFAULT);
        map.put(KORYPHE_VERSION, KORYPHE_VERSION_DEFAULT);
        return Collections.unmodifiableMap(map);
    }

    private PropertiesUtil() {
    }

    public static Map<String, String> getProperties() {
        final Map<String, String> properties = new LinkedHashMap<>();
        final String customPropNamesCsv = System.getProperty(EXPOSED_PROPERTIES);
        final Stream<String> customPropNames = null != customPropNamesCsv ? Arrays.stream(customPropNamesCsv.split(",")) : Stream.empty();
        Stream.concat(CORE_EXPOSED_PROPERTIES.keySet().stream(), customPropNames)
                .filter(StringUtils::isNotEmpty)
                .forEach(prop -> {
                    String value = System.getProperty(prop);
                    if (null == value) {
                        value = CORE_EXPOSED_PROPERTIES.get(prop);
                    }
                    properties.put(prop, value);
                });

        return Collections.unmodifiableMap(properties);
    }

    public static String getProperty(final String propertyName) {
        return getProperties().get(propertyName);
    }
}


text:
import argparse
import logging
import os
import sys

from vaspy import PY2
if PY2:
    import commands as subprocess
else:
    import subprocess

import numpy as np

from vaspy.iter import OutCar
from vaspy.matstudio import XsdFile
from vaspy.functions import str2list

_logger = logging.getLogger("vaspy.script")

# Set arguments parser.
parser = argparse.ArgumentParser()
parser.add_argument("--xsd", help="create MaterStudio .xsd file",
                    action="store_true")
args = parser.parse_args()

outcar = OutCar()
pos, forces = outcar.forces(-1)
idx = outcar.last_max_atom - 1
pos = pos[idx]
forces = forces[idx]

_logger.info("{:<15s}: {}".format("max force atom", outcar.last_max_atom))
_logger.info("{:<15s}: ({}, {}, {})".format("atom position", *pos))
_logger.info("{:<15s}: {}, {}, {}".format("forces", *forces))
_logger.info("{:<15s}: {}\n".format("total-force", outcar.last_max_force))

# Get fort.188 info.
if os.path.exists('./fort.188'):
    with open('fort.188', 'r') as f:
        atom_info = f.readlines()[5]
    _logger.info("{:<10s}{:<10s}{:<15s}".format("Atom1", "Atom2", "DISTANCE"))
    _logger.info("-"*30)
    _logger.info("{:<10s}{:<10s}{:<15s}\n".format(*str2list(atom_info)))

# Create .xsd file.
if args.xsd:
    status, output = subprocess.getstatusoutput('ls *.xsd | head -1')
    if not output.endswith('.xsd'):
        _logger.info("No .xsd file in current directory.")
        sys.exit(1)
    xsd = XsdFile(filename=output)
    # modify atom color
    xsd.modify_color(atom_number=outcar.last_max_atom)
    jobname = output.split('.')[0]
    filename = jobname + '-force.xsd'
    xsd.tofile(filename=filename)
    _logger.info(filename + " has been created.")