Skip to content

Instantly share code, notes, and snippets.

@mvirkkunen
Created May 18, 2014 21:06
Show Gist options
  • Save mvirkkunen/1deb255a709cba799601 to your computer and use it in GitHub Desktop.
Save mvirkkunen/1deb255a709cba799601 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Text;
using Thrift.Transport;
namespace LineNet.Implementation
{
/// <summary>
/// HTTP client that supports LINE features such as persisted headers and authentication
/// </summary>
public class LineHttpTransport : TTransport
{
TcpClient client;
SslStream ssl;
BufferedStream buffered;
bool firstRequest;
MemoryStream input, output;
string Path;
string AuthToken;
string LS;
string Host = "gd2.line.naver.jp";
int Port = 443;
string ApplicationName = "DESKTOPWIN\t3.2.1.83\tWINDOWS\t5.1.2600-XP-x64";
volatile bool _IsBusy;
public bool IsBusy
{
get { return _IsBusy; }
}
public LineHttpTransport(string path, string authToken)
{
this.Path = path;
this.AuthToken = authToken;
}
public override void Open()
{
client = new TcpClient();
client.Connect(Host, Port);
ssl = new SslStream(client.GetStream(), false, delegate { return true; });
ssl.AuthenticateAsClient(Host);
buffered = new BufferedStream(ssl);
output = new MemoryStream();
input = new MemoryStream();
firstRequest = true;
}
public override void Close()
{
if (client == null)
return;
buffered.Close();
buffered = null;
ssl.Close();
ssl = null;
client.Close();
client = null;
input.Close();
input = null;
output.Close();
output = null;
}
public override int Read(byte[] buf, int off, int len)
{
return input.Read(buf, off, len);
}
public override void Write(byte[] buf, int off, int len)
{
output.Write(buf, off, len);
}
public override void Flush()
{
StringBuilder req = new StringBuilder();
req.AppendFormat("POST {0} HTTP/1.1\r\n", Path);
if (LS != null)
req.AppendFormat("X-LS: {0}\r\n", LS);
if (firstRequest)
{
req.AppendFormat("Host: {0}:{1}\r\n", Host, Port);
req.Append("Connection: Keep-Alive\r\n"
+ "Content-Type: application/x-thrift\r\n"
+ "Accept: application/x-thrift\r\n"
+ "User-Agent: LineNet\r\n");
req.AppendFormat("X-Line-Application: {0}\r\n", ApplicationName);
if (AuthToken != null)
req.AppendFormat("X-Line-Access: {0}\r\n", AuthToken ?? "-");
firstRequest = false;
}
req.AppendFormat("Content-Length: {0}\r\n", output.Length);
req.Append("\r\n");
byte[] headerBytes = Encoding.UTF8.GetBytes(req.ToString());
buffered.Write(headerBytes, 0, headerBytes.Length);
output.Position = 0;
output.CopyTo(buffered);
buffered.Flush();
output = new MemoryStream();
input = new MemoryStream();
string[] requestLine = buffered.ReadLine().Split(new [] { ' ' }, 3);
int code = Int32.Parse(requestLine[1]);
int contentLength = 0;
string line;
while ((line = buffered.ReadLine()) != "")
{
string[] parts = line.Split(new[] { ' ' }, 2);
string header = parts[0].ToLower(), value = parts[1];
switch (header)
{
case "x-ls:":
LS = value;
break;
case "content-length:":
contentLength = Int32.Parse(value);
break;
}
}
byte[] buf = new byte[4096];
int nleft = contentLength;
while (nleft > 0)
{
int nread = buffered.Read(buf, 0, Math.Min(contentLength, buf.Length));
if (nread <= 0)
throw new LineHttpException(-1);
input.Write(buf, 0, nread);
nleft -= nread;
}
input.Position = 0;
if (code != 200)
throw new LineHttpException(code);
}
protected override void Dispose(bool disposing)
{
Close();
}
public override bool IsOpen
{
get { return client != null; }
}
}
static class StreamExtensionMethods
{
internal static string ReadLine(this BufferedStream s)
{
var ms = new MemoryStream(64);
int b;
while ((b = s.ReadByte()) != -1 && b != '\n')
{
if (b != '\r')
ms.WriteByte((byte)b);
}
return (ms.Length == 0) ? "" : Encoding.UTF8.GetString(ms.ToArray());
}
}
class LineHttpException : Exception
{
public int StatusCode { get; set; }
public LineHttpException(int statusCode) : base("HTTP " + statusCode)
{
this.StatusCode = statusCode;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment