text:
layout: post
title:  "HTTP Server in Go"
date:   2017-07-12 11:40:09 -0400
categories: server http networking golang go
---

Last week, I started my batch at Recurse Center! For my first project, I implemented an HTTP server using sockets.

# What is an HTTP server?
**HTTP** (aka HyperText Transfer Protocol) is how the internet is able to show us stuff! It's an application layer protocol that specifies a set of rules for how requests and responses should be formatted so that web clients and web servers can communicate. A **server** is a piece of software that takes an HTTP request from a client and returns an HTTP response to that requesting client (which is often a web browser). But this definition feels pretty vague to me. How does the request actually get to and from this _software_? And what is this software actually doing?

# Sockets & Connections
Sockets are how clients and servers are able to communicate! In the context of this post, we'll only be talking about TCP connections. A **socket** is a combination of an IP address and a port so the TCP layer can identify where the data should be sent. Both the client and the server need to create a socket in order to form a **connection** that can transport data back and forth.

You can think of sockets as old school telephones and a connection as the cord between them.

Let's check out this simple server implementation.

{% highlight golang %}
package main

import (
  "bufio"
  "fmt"
  "net"
)

func handleConnection(conn net.Conn) {

  defer conn.Close()

  scanner := bufio.NewScanner(conn)
  scanner.Scan()

  // This grabs the first line of the request
  requestStr := scanner.Text()

  var headers string
  var body []byte

  headers = "HTTP/1.1 200 OK\r\n\r\n"
  body = []byte("Hello, World!")

  // Write response to connection
  conn.Write([]byte(headers))
  conn.Write(body)
}

func main() {
  l, err := net.Listen("tcp", ":8888")
  if err != nil {
    fmt.Println(err)
  }
  defer l.Close()
  fmt.Println("Listening at :8888...")

  for {
    // Wait for a connection.
    conn, err := l.Accept()
    if err != nil {
      fmt.Println(err)
    }
    // Handle the connection in a new goroutine.
    // The loop then returns to accepting, so that
    // multiple connections may be served concurrently.
    go handleConnection(conn)
  }
}
{% endhighlight %}

The main function creates a TCP socket at localhost:8080 and begins waiting for a connection.
Once the server-side socket receives a connection the function handleConnection deals with the connection in a new thread. This is so multiple users may request data from the server at one time. handleConnection reads the HTTP request from the connection and returns an HTTP response. In this case, it just reads the first line of the HTTP request (ex. GET / HTTP/1.1) and automatically returns a successful HTTP response by writing to the connection.

Remember the socket/connection phone analogy? A handler is like calling your friend to ask a question like "Where do you want to get dinner?" And your friend thinks for a second processing your questions - possibly thinking through potential dinner options

Then she returns an answer!

So the handler function takes an HTTP request from the connection, processes it, and returns an HTTP response back to the connection!

This is how we're able to see webpages, which I think is pretty cool.

I went on to abstract this further so you can easily add routes to your server, but this was my main takeaway! You can check out [my project](https://github.com/aftaberski/http-web-server) on Github.


text:
<?php
/**
 * Show messages
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/notices/success.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
 * will need to copy the new files to your theme to maintain compatibility. We try to do this.
 * as little as possible, but it does happen. When this occurs the version of the template file will.
 * be bumped and the readme will list any important changes.
 *
 * @see 	    http://docs.woothemes.com/document/template-structure/
 * @author 		WooThemes
 * @package 	WooCommerce/Templates
 * @version     1.6.4
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

if ( ! $messages ){
	return;
}

?>

<?php foreach ( $messages as $message ) : ?>

                <?php echo wp_kses_post( $message ); ?>

<?php endforeach; ?>

redpajama_set_name: RedPajamaGithub


text:
using AutoMapper;
using Shkembedjijnica.App.Core.DTOs;
using Shkembedjijnica.Models;

namespace Shkembedjijnica.App.Core
{
    public class ShkemedjijnicaProfile : Profile
    {
        public ShkemedjijnicaProfile()
        {
            CreateMap<Employee, EmployeeDto>().ReverseMap();

            CreateMap<Employee, ManagerDto>()
                .ForMember(dest => dest.EmployeeDtos,
                            opt => opt.MapFrom(src => src.EmployeesManager))
                .ReverseMap();

            CreateMap<Employee, EmployeeFullInfoDto>().ReverseMap();

            CreateMap<Employee, AgeComparingEmployeeDto>().ReverseMap();
        }
    }
}


text:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace SourceCode.Clay.AspNetCore.Middleware.Correlation.Tests.Mocks
{
    public class MockMiddleware
    {
        private Action<HttpContext> _onInvoke;
        private RequestDelegate _next;

        public MockMiddleware(Action<HttpContext> onInvoke = default, RequestDelegate next = default)
        {
            _onInvoke = onInvoke;
            _next = next;
        }

        public bool WasCalled { get; private set; }
        public string WithTraceIdentifier { get; private set; }

        public Task Invoke(HttpContext context)
        {
            WasCalled = true;
            WithTraceIdentifier = context?.TraceIdentifier;

            _onInvoke?.Invoke(context);

            if (_next != default)
                return _next(context);
            else
                return Task.CompletedTask;
        }

        public static implicit operator RequestDelegate(MockMiddleware value)
        {
            return value.ToRequestDelegate();
        }

        public RequestDelegate ToRequestDelegate()
        {
            return new RequestDelegate(this.Invoke);
        }
    }
}


text:
cask "chia" do
  arch arm: "-arm64"

  version "1.5.0"

  on_intel do
    sha256 "0db183c1ffb31badbc77899f2cdafaca33eca5432d2f3f01c4cf21f614b663c5"
  end
  on_arm do
    sha256 "d5e18d5571fc5ae5185cdf55d2abae0a41d4f3fade57f15775ac876e7463be0f"
  end

  url "https://github.com/Chia-Network/chia-blockchain/releases/download/#{version}/Chia-#{version}#{arch}.dmg",
      verified: "github.com/Chia-Network/chia-blockchain/"
  name "Chia Blockchain"
  desc "GUI Python implementation for the Chia blockchain"
  homepage "https://www.chia.net/"

  livecheck do
    url :url
    strategy :github_latest
  end

  app "Chia.app"

  zap trash: [
    "~/Library/Application Support/Chia Blockchain",
    "~/Library/Preferences/net.chia.blockchain.plist",
    "~/Library/Saved Application State/net.chia.blockchain.savedState",
    "~/.chia",
  ]
end


text:
layout: post
date: 2016-09-22
title: "Jenny Packham Stella Short Sleeves Sweep/Brush Train Aline/Princess"
category: Jenny Packham
tags: [Jenny Packham ,Jenny Packham,Aline/Princess ,Off The Shoulder,Sweep/Brush Train,Short Sleeves]
---
### Jenny Packham Stella
Just **$409.99**
###   Short Sleeves Sweep/Brush Train Aline/Princess

BRANDS	Jenny Packham

Silhouette	Aline/Princess

Neckline	Off The Shoulder

Hemline/Train	Sweep/Brush Train

Sleeve	Short Sleeves

Buy it: [https://www.readybrides.com/en/jenny-packham-/35432-jenny-packham-stella.html](https://www.readybrides.com/en/jenny-packham-/35432-jenny-packham-stella.html)


text:
#ifdef GIT_OPENSSL

#include <ctype.h>

#include "global.h"
#include "posix.h"
#include "stream.h"
#include "socket_stream.h"
#include "netops.h"
#include "git2/transport.h"

#ifdef GIT_CURL
# include "curl_stream.h"
#endif

#ifndef GIT_WIN32
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
#endif

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include <openssl/bio.h>

static int bio_create(BIO *b)
{
	b->init = 1;
	b->num = 0;
	b->ptr = NULL;
	b->flags = 0;

	return 1;
}

static int bio_destroy(BIO *b)
{
	if (!b)
		return 0;

	b->init = 0;
	b->num = 0;
	b->ptr = NULL;
	b->flags = 0;

	return 1;
}

static int bio_read(BIO *b, char *buf, int len)
{
	git_stream *io = (git_stream *) b->ptr;
	return (int) git_stream_read(io, buf, len);
}

static int bio_write(BIO *b, const char *buf, int len)
{
	git_stream *io = (git_stream *) b->ptr;
	return (int) git_stream_write(io, buf, len, 0);
}

static long bio_ctrl(BIO *b, int cmd, long num, void *ptr)
{
	GIT_UNUSED(b);
	GIT_UNUSED(num);
	GIT_UNUSED(ptr);

	if (cmd == BIO_CTRL_FLUSH)
		return 1;

	return 0;
}

static int bio_gets(BIO *b, char *buf, int len)
{
	GIT_UNUSED(b);
	GIT_UNUSED(buf);
	GIT_UNUSED(len);
	return -1;
}

static int bio_puts(BIO *b, const char *str)
{
	return bio_write(b, str, strlen(str));
}

static BIO_METHOD git_stream_bio_method = {
	BIO_TYPE_SOURCE_SINK,
	"git_stream",
	bio_write,
	bio_read,
	bio_puts,
	bio_gets,
	bio_ctrl,
	bio_create,
	bio_destroy
};

static int ssl_set_error(SSL *ssl, int error)
{
	int err;
	unsigned long e;

	err = SSL_get_error(ssl, error);

	assert(err != SSL_ERROR_WANT_READ);
	assert(err != SSL_ERROR_WANT_WRITE);

	switch (err) {
	case SSL_ERROR_WANT_CONNECT:
	case SSL_ERROR_WANT_ACCEPT:
		giterr_set(GITERR_NET, "SSL error: connection failure\n");
		break;
	case SSL_ERROR_WANT_X509_LOOKUP:
		giterr_set(GITERR_NET, "SSL error: x509 error\n");
		break;
	case SSL_ERROR_SYSCALL:
		e = ERR_get_error();
		if (e > 0) {
			giterr_set(GITERR_NET, "SSL error: %s",
					ERR_error_string(e, NULL));
			break;
		} else if (error < 0) {
			giterr_set(GITERR_OS, "SSL error: syscall failure");
			break;
		}
		giterr_set(GITERR_NET, "SSL error: received early EOF");
		return GIT_EEOF;
		break;
	case SSL_ERROR_SSL:
		e = ERR_get_error();
		giterr_set(GITERR_NET, "SSL error: %s",
				ERR_error_string(e, NULL));
		break;
	case SSL_ERROR_NONE:
	case SSL_ERROR_ZERO_RETURN:
	default:
		giterr_set(GITERR_NET, "SSL error: unknown error");
		break;
	}
	return -1;
}

static int ssl_teardown(SSL *ssl)
{
	int ret;

	ret = SSL_shutdown(ssl);
	if (ret < 0)
		ret = ssl_set_error(ssl, ret);
	else
		ret = 0;

	SSL_free(ssl);
	return ret;
}

static int check_host_name(const char *name, const char *host)
{
	if (!strcasecmp(name, host))
		return 0;

	if (gitno__match_host(name, host) < 0)
		return -1;

	return 0;
}

static int verify_server_cert(SSL *ssl, const char *host)
{
	X509 *cert;
	X509_NAME *peer_name;
	ASN1_STRING *str;
	unsigned char *peer_cn = NULL;
	int matched = -1, type = GEN_DNS;
	GENERAL_NAMES *alts;
	struct in6_addr addr6;
	struct in_addr addr4;
	void *addr;
	int i = -1,j;

	if (SSL_get_verify_result(ssl) != X509_V_OK) {
		giterr_set(GITERR_SSL, "The SSL certificate is invalid");
		return GIT_ECERTIFICATE;
	}

	/* Try to parse the host as an IP address to see if it is */
	if (p_inet_pton(AF_INET, host, &addr4)) {
		type = GEN_IPADD;
		addr = &addr4;
	} else {
		if(p_inet_pton(AF_INET6, host, &addr6)) {
			type = GEN_IPADD;
			addr = &addr6;
		}
	}

	cert = SSL_get_peer_certificate(ssl);
	if (!cert) {
		giterr_set(GITERR_SSL, "the server did not provide a certificate");
		return -1;
	}

	/* Check the alternative names */
	alts = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
	if (alts) {
		int num;

		num = sk_GENERAL_NAME_num(alts);
		for (i = 0; i < num && matched != 1; i++) {
			const GENERAL_NAME *gn = sk_GENERAL_NAME_value(alts, i);
			const char *name = (char *) ASN1_STRING_data(gn->d.ia5);
			size_t namelen = (size_t) ASN1_STRING_length(gn->d.ia5);

			/* Skip any names of a type we're not looking for */
			if (gn->type != type)
				continue;

			if (type == GEN_DNS) {
				/* If it contains embedded NULs, don't even try */
				if (memchr(name, '\0', namelen))
					continue;

				if (check_host_name(name, host) < 0)
					matched = 0;
				else
					matched = 1;
			} else if (type == GEN_IPADD) {
				/* Here name isn't so much a name but a binary representation of the IP */
				matched = !!memcmp(name, addr, namelen);
			}
		}
	}
	GENERAL_NAMES_free(alts);

	if (matched == 0)
		goto cert_fail_name;

	if (matched == 1)
		return 0;

	/* If no alternative names are available, check the common name */
	peer_name = X509_get_subject_name(cert);
	if (peer_name == NULL)
		goto on_error;

	if (peer_name) {
		/* Get the index of the last CN entry */
		while ((j = X509_NAME_get_index_by_NID(peer_name, NID_commonName, i)) >= 0)
			i = j;
	}

	if (i < 0)
		goto on_error;

	str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(peer_name, i));
	if (str == NULL)
		goto on_error;

	/* Work around a bug in OpenSSL whereby ASN1_STRING_to_UTF8 fails if it's already in utf-8 */
	if (ASN1_STRING_type(str) == V_ASN1_UTF8STRING) {
		int size = ASN1_STRING_length(str);

		if (size > 0) {
			peer_cn = OPENSSL_malloc(size + 1);
			GITERR_CHECK_ALLOC(peer_cn);
			memcpy(peer_cn, ASN1_STRING_data(str), size);
			peer_cn[size] = '\0';
		}
	} else {
		int size = ASN1_STRING_to_UTF8(&peer_cn, str);
		GITERR_CHECK_ALLOC(peer_cn);
		if (memchr(peer_cn, '\0', size))
			goto cert_fail_name;
	}

	if (check_host_name((char *)peer_cn, host) < 0)
		goto cert_fail_name;

	OPENSSL_free(peer_cn);

	return 0;

on_error:
	OPENSSL_free(peer_cn);
	return ssl_set_error(ssl, 0);

cert_fail_name:
	OPENSSL_free(peer_cn);
	giterr_set(GITERR_SSL, "hostname does not match certificate");
	return GIT_ECERTIFICATE;
}

typedef struct {
	git_stream parent;
	git_stream *io;
	bool connected;
	char *host;
	SSL *ssl;
	git_cert_x509 cert_info;
} openssl_stream;

int openssl_close(git_stream *stream);

int openssl_connect(git_stream *stream)
{
	int ret;
	BIO *bio;
	openssl_stream *st = (openssl_stream *) stream;

	if ((ret = git_stream_connect(st->io)) < 0)
		return ret;

	st->connected = true;

	bio = BIO_new(&git_stream_bio_method);
	GITERR_CHECK_ALLOC(bio);
	bio->ptr = st->io;

	SSL_set_bio(st->ssl, bio, bio);
	/* specify the host in case SNI is needed */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	SSL_set_tlsext_host_name(st->ssl, st->host);
#endif

	if ((ret = SSL_connect(st->ssl)) <= 0)
		return ssl_set_error(st->ssl, ret);

	return verify_server_cert(st->ssl, st->host);
}

int openssl_certificate(git_cert **out, git_stream *stream)
{
	openssl_stream *st = (openssl_stream *) stream;
	int len;
	X509 *cert = SSL_get_peer_certificate(st->ssl);
	unsigned char *guard, *encoded_cert;

	/* Retrieve the length of the certificate first */
	len = i2d_X509(cert, NULL);
	if (len < 0) {
		giterr_set(GITERR_NET, "failed to retrieve certificate information");
		return -1;
	}

	encoded_cert = git__malloc(len);
	GITERR_CHECK_ALLOC(encoded_cert);
	/* i2d_X509 makes 'guard' point to just after the data */
	guard = encoded_cert;

	len = i2d_X509(cert, &guard);
	if (len < 0) {
		git__free(encoded_cert);
		giterr_set(GITERR_NET, "failed to retrieve certificate information");
		return -1;
	}

	st->cert_info.cert_type = GIT_CERT_X509;
	st->cert_info.data = encoded_cert;
	st->cert_info.len = len;

	*out = (git_cert *)&st->cert_info;
	return 0;
}

static int openssl_set_proxy(git_stream *stream, const char *proxy_url)
{
	openssl_stream *st = (openssl_stream *) stream;

	return git_stream_set_proxy(st->io, proxy_url);
}

ssize_t openssl_write(git_stream *stream, const char *data, size_t len, int flags)
{
	openssl_stream *st = (openssl_stream *) stream;
	int ret;

	GIT_UNUSED(flags);

	if ((ret = SSL_write(st->ssl, data, len)) <= 0) {
		return ssl_set_error(st->ssl, ret);
	}

	return ret;
}

ssize_t openssl_read(git_stream *stream, void *data, size_t len)
{
	openssl_stream *st = (openssl_stream *) stream;
	int ret;

	if ((ret = SSL_read(st->ssl, data, len)) <= 0)
		ssl_set_error(st->ssl, ret);

	return ret;
}

int openssl_close(git_stream *stream)
{
	openssl_stream *st = (openssl_stream *) stream;
	int ret;

	if (st->connected && (ret = ssl_teardown(st->ssl)) < 0)
		return -1;

	st->connected = false;

	return git_stream_close(st->io);
}

void openssl_free(git_stream *stream)
{
	openssl_stream *st = (openssl_stream *) stream;

	git__free(st->host);
	git__free(st->cert_info.data);
	git_stream_free(st->io);
	git__free(st);
}

int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
{
	int error;
	openssl_stream *st;

	st = git__calloc(1, sizeof(openssl_stream));
	GITERR_CHECK_ALLOC(st);

#ifdef GIT_CURL
	error = git_curl_stream_new(&st->io, host, port);
#else
	error = git_socket_stream_new(&st->io, host, port);
#endif

	if (error < 0)
		return error;

	st->ssl = SSL_new(git__ssl_ctx);
	if (st->ssl == NULL) {
		giterr_set(GITERR_SSL, "failed to create ssl object");
		return -1;
	}

	st->host = git__strdup(host);
	GITERR_CHECK_ALLOC(st->host);

	st->parent.version = GIT_STREAM_VERSION;
	st->parent.encrypted = 1;
	st->parent.proxy_support = git_stream_supports_proxy(st->io);
	st->parent.connect = openssl_connect;
	st->parent.certificate = openssl_certificate;
	st->parent.set_proxy = openssl_set_proxy;
	st->parent.read = openssl_read;
	st->parent.write = openssl_write;
	st->parent.close = openssl_close;
	st->parent.free = openssl_free;

	*out = (git_stream *) st;
	return 0;
}

#else

#include "stream.h"

int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
{
	GIT_UNUSED(out);
	GIT_UNUSED(host);
	GIT_UNUSED(port);

	giterr_set(GITERR_SSL, "openssl is not supported in this version");
	return -1;
}

#endif


text:
@interface RealmTestClass0 : RLMObject

@property NSInteger integerValue;
@property NSString *stringValue;

@end

RLM_ARRAY_TYPE(RealmTestClass0)

@interface RealmTestClass1 : RLMObject

@property NSInteger integerValue;
@property BOOL boolValue;
@property float floatValue;
@property double doubleValue;
@property NSString *stringValue;
@property NSDate *dateValue;
@property RLMArray<RealmTestClass0> *arrayReference;

@end

@interface RealmTestClass2 : RLMObject

@property NSInteger integerValue;
@property BOOL boolValue;
@property RealmTestClass1 *objectReference;

@end


text:
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32Fxxx_IT_H
#define __STM32Fxxx_IT_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */

void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void EXTI15_10_IRQHandler(void);
void OTG_HS_WKUP_IRQHandler(void);
void OTG_HS_IRQHandler(void);
void OTG_HS_EP1_IN_IRQHandler(void);
void OTG_HS_EP1_OUT_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void OTG_FS_WKUP_IRQHandler(void);
void OTG_FS_IRQHandler(void);

#ifdef __cplusplus
}
#endif

#endif /* __STM32Fxxx_IT_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


text:
"use strict";

const config = require("config");
const Toshihiko = require("toshihiko");

let toshihiko = new Toshihiko.Toshihiko(
        config.mysql.database,
        config.mysql.username,
        config.mysql.password,
        config.mysql);

toshihiko.TYPE = Toshihiko.Type;

module.exports = toshihiko;