Profile

Click to view full profile
Hi, I'm Veerapat Sriarunrungrueang, an expert in technology field, especially full stack web development and performance testing.This is my coding diary. I usually develop and keep code snippets or some tricks, and update to this diary when I have time. Nowadays, I've been giving counsel to many well-known firms in Thailand.
view more...
Showing posts with label Internet Technology. Show all posts
Showing posts with label Internet Technology. Show all posts

Sunday, January 13, 2019

My to-read for Microservice


For me, the term Microservice in conceptual level is not new. I think it not much different from SOA. The different is just about how the term define how deep to decoupling/separate in programming level. Recently, with many development teams working on different features. Without causing and impact when changes, they have to be separate to each other which is not new. But now with the technogy improved, and tools are much more powerful. they help a lot to develop with Microservice architecture from start to finish a feature without worry in impact to other features.

Recently, I started to read and research more in details because of facing this problems. There are many sub features/modules in 1 product. Each have to work with different teams. In order to reduce an impact when deploy. I started to think about Microservice.

Concepts:

Before, I was thinking how they dealing with transactions because in monolithic software, it is usually connect to 1 or few data systems. So, they need to work around to cover and make it work by creating a rollback request.

Moreover, with many Microservices, I started to think about how they can working together. Because if many services working together and we have 1 service to Orchestrate them. I think this part will be tightly couple as same as monolithic software did. The link below is not solve the issues. It just talking about how many services can connect in easiest way, less impact and effort by using Kubernetes.

Programming:

Wednesday, May 2, 2018

Convert Microsoft Word (Thai language) to PDF without format or layout changed

There are many libraries out there to convert text into PDF or docx into PDF file. However, recently, I found the problem in Thai language which they usually use "Justify" alignment for their document. But for most of the libraries I found even paid the money one, they have problem in word segmentation. It will result in they can not do Justify alignment properly which very look like to align on the left.

In order to resolve this issue, I had tried to search many possible way to do it which are:
  • Use Microsoft Office Interop
  • Use Word Automation Services in SharePoint 2013
For the first solution, it is quite to easy to implement it. For example, follow the link below:

However, to use Interop, it won't work well on Server-Client architecture e.g. Web Server. It will similar to open Microsoft Word window for each request, which consume a lot of memory as described here: 

The first solution, I tried to implement it once on Web Server but fail due to it has an unknown formatting problem during convert on Web Server (this issue was not found when I try it as Console Application). The PDF file spacing was different from the master docx file for unknown reason.

Later on I found that if we have SharePoint 2013. We can use Word Automation Services which is available from SharePoint 2010 (but as job conversion). To do on demand conversion, it is available on SharePoint 2013. It is very suitable in Web Server solution, and found no issue during convert Thai docx into PDF file.

By the way, in order to run Word Automation Services. It is very important that the machine that run this service must not be the same machine that installed Active Directory, it will result in service does not work (sorry, I can't remember the error message, but it will stuck for awhile before throwing an error). It can be converted from many formats e.g. stream, file location, and byte array.

To use Word Automation Services in C#:
Below is the example cut from the reference link above as snippet. Replace "WORD_AUTOMATION_SERVICE" with your registered service name.
using (MemoryStream destinationStream = new MemoryStream())
{
     //Call the syncConverter class, passing in the name of the Word Automation Service for your Farm.
     SyncConverter sc = new SyncConverter(WORD_AUTOMATION_SERVICE);
     //Pass in your User Token or credentials under which this conversion job is executed.
     sc.UserToken = SPContext.Current.Site.UserToken;
     sc.Settings.UpdateFields = true;
 
     //Save format
     sc.Settings.OutputFormat = SaveFormat.PDF; 
 
     //Convert to PDF by opening the file stream, and then converting to the destination memory stream.
     ConversionItemInfo info = sc.Convert(li.File.OpenBinaryStream(), destinationStream);
 
     var filename = Path.GetFileNameWithoutExtension(li.File.Name) + ".pdf";
     if (info.Succeeded)
     {
          //File conversion successful, then add the memory stream to the SharePoint list.
          SPFile newfile = library.RootFolder.Files.Add(filename, destinationStream, true);
     }
     else if (info.Failed)
     {
          throw new Exception(info.ErrorMessage);
     }
}
In the end, I would like to share my research for this issue because it used quite some time before I found the solution. Hope it can help ^^.

Friday, September 9, 2016

SSRS - By pass specific user to Reporting Server

When we browse to Reporting Server, it usually ask a username and password to access. However, sometime we want to avoid that by using specific account (treat like webapp that know db password). To do that we have to implement a custom web application that host a web page which can load ReportViewer. Then that page have to specifically implement parameter specification before by pass its parameters to ReportViewer control. The steps are shown below:

By pass anonymous access for reports using custom web app as a proxy
  1. Create ReportViewer in custom web app

Create self WCF Windows Service

Tuesday, May 19, 2015

Archeblade Internet Server Configuration

To configure Archeblade server, do the following steps:
  1. by default Archeblade server use 3 ports starting with port 7777. For example, if the textbox in Port Num is 7777, it will use ports 7777-7779.
  2. Firewall: disabled or add Inbound Rules in Advance Firewall settings. Then, allow TDP for ports 7777-7779 and another one for UDP in the same ports.
  3. Configure your router for Port-Forwarding to receive incoming port 7777 to local port 7777 on your specific server ip address for both TCP and UDP.                      
  4. Do step 3 more for port 7778 and 7779.
  5. Done

Thursday, October 24, 2013

Web Test Recorder on Internet Explorer 11

Recently, I have got a problem about using Web Test Recorder after upgrading to Windows 8.1. It has come with the new version of internet explorer i.e. version 11. That doesn't compatible with current Web Test Recorder version (we have to wait until new release to support IE11). However, there is a workaround for this problem. Try to disable Enhanced Protected Mode, then it should work. If not, follow this link: http://blogs.msdn.com/b/visualstudioalm/archive/2013/09/16/using-internet-explorer-11-and-not-able-to-record-a-web-performance-test-successfully.aspx. It contains information to disable something new which doesn't support on Web Test Recorder.

Wednesday, July 24, 2013

JavaScript class and namespace

The following links are the basic link provide the information how to create namspace and class in JavaScript.
The following example is to show how to create basic namespace and class. The namespace is name "NS" then create class in that namespace "Sound". Sound class has instance variable "name". and class variable "Variable". Also has the class method "Method1" and "Method2" which can be used like static method in Java or C#. After that this html page will be processed when document loaded and print out "love story 3".
<!DOCTYPE html>
<html>
 <head>
  <title>Test</title>
  <script type="text/javascript">
  var NS = NS || {};
  
  NS.Sound = function (name) {
   this.name = name;
  }
  
  NS.Sound.Variable = [];
  
  NS.Sound.Method1 = function () {
   NS.Sound.Variable.push(1);
   NS.Sound.Variable.push(2);
   NS.Sound.Variable.push(3);
  }
  
  NS.Sound.Method2 = function () {
   return NS.Sound.Variable.length;
  }
  
  function onLoad() {
   var sound = new NS.Sound("lovestory");
   var div = document.getElementById("content");
   
   NS.Sound.Method1();
   var content = sound.name + " " + NS.Sound.Method2();
   
   div.innerHTML = content;
  }
  
  document.addEventListener("DOMContentLoaded", onLoad, false);
  </script>
 </head>
 <body>
  <div id="content"></div>
 </body>
</html>

Monday, July 8, 2013

Download ISO files from IIS

Normally IIS won't allow the clients to contact unknown extensions in the server. ISO is not set by IIS default. In order to do that, we need to configure MIME Types on IIS with the following steps:
- Open IIS.
- Select the the server then select MIME Types.
- Add .iso extension as application/octet-stream.
- Ok

After that you can access ISO as octet steam which can be applied to almost any binary file.

Friday, February 15, 2013

Change IE security setting to normal in Windows Server 2012

By default Internet Explorer (IE) in Windows Server is protected with some security to prevent unintentionally attacked during browse internet. Sometimes, we want it to be just a normal IE that trusts how user use it. In order to do that in Windows Server 2012 is described as follows:

Firstly, opens Server Manager page.


Next, on the top of Dashboard under welcoming message, clicks at "Configure this local server" as shown picture below.

Then, on properties tab, you will see information is divided into 2 sides. Look at the right side. You will see "IE Enhanced Security Configuration", it should be on if your IE is still protected. So, we gonna change it off. by click at it.

After you click it, a popup will be opened. Your job is changing to off as shown below.

Click OK and wait for a while during system setting is changing. When it finished, you will notice on properties tab "IE Enhanced Security Configuration" is changed to Off.

Sunday, January 27, 2013

Image POST Client and Sever in Python and C#

From last time, I had told how to encode image into base64 string[1], and how to do POST message to HTTP server[2][3] This post will continue from those posts. First, we will create HTTP POST server in Python. I based on the concept that a message will be encoded using url-encode format in a form of base64 string, and the image string will be sent to a variable named "img". It will decode an image string from that variable.
import SimpleHTTPServer
import SocketServer
import cgi
from base64 import decodestring

PORT = 8000

class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

 def _writeheaders(self):
  self.send_response(200)
  self.send_header('Content-type', 'text/html')
  self.end_headers()

 def do_GET(self):
  filename = 'temp.png'
  f = open(filename, 'rb')
  encode = f.read().encode('base64')
  img = '<img height="200" src="data:image/png;base64,' + encode + '" width="250" />'
  self._writeheaders()
  self.wfile.write("""
  <html><head><title>Simple Server</title></head>
   <body>
    It worked!!!!
 
    %s
   </body>
  </html>"""  % (img))
 def do_POST(self):
  form = cgi.FieldStorage(
   fp=self.rfile,
   headers=self.headers,
   environ={'REQUEST_METHOD':'POST',
      'CONTENT_TYPE':self.headers['Content-Type'],
     })
  encode = form['img'].value
  decode = decodestring(encode)
  output = open('temp.png', 'wb')
  output.write(decode)
  output.close()
  # After posting image has done, it will response GET message to show that image
  self.do_GET()

Handler = ServerHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()
Then, we will create HTTP POST client to upload an image to our HTTP POST server.
Python:
import urllib, urllib2

uri = 'http://localhost:8000'
filename = 'Leafa.jpg'
f = open(filename, 'rb')
encode = f.read().encode('base64')
params = { 'img' : encode }
data = urllib.urlencode(params)

p = urllib2.urlopen(uri, data)
print p.read()
C# WPF:
string fileName = "Leafa.jpg";
StreamResourceInfo sri = null;
Uri uri = new Uri(fileName, UriKind.Relative);
sri = Application.GetResourceStream(uri);

using (var memoryStream = new MemoryStream())
{
    sri.Stream.CopyTo(memoryStream);
    byte[] result = memoryStream.ToArray();
    var base64 = "img=" + HttpUtility.UrlEncode(System.Convert.ToBase64String(result));

    MessageBox.Show(base64);

    using (var wc = new WebClient())
    {
        wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
        wc.UploadStringCompleted += wc_UploadStringCompleted;
        wc.UploadStringAsync(new Uri(url), "POST", base64);
    }
}
The server will response a web page, which the client will show that response as a text format, so, if you want to make sure that your image are already uploaded, just check it the "server.py" directory. You will see the image named "temp.png", which is converted from jpg image in the client side. Moreover, you can use a web browser request to http://localhost:8000 to let GET response show you that uploaded one.

The sample project is uploaded, can download from http://www.mediafire.com/?1okv3lc6nk1jsc7.

Leafa.jpg
References:
  1. Encode an Image into base64 string in C# / Python
  2. Simple HTTP POST Server / Client with Python
  3. HTTP POST data via WebClient and WebRequest

Friday, January 25, 2013

Windows Azure Errors Guide

If you face provisioning timed out during restore virtual machine from image file: Azure (IaaS) Provisioning Timed Out.

If you face the provisioning operation is too long, look at "The operation cannot be performed because the virtual machine is faulted."

P.S. If I find anymore unexpected errors, I will update to this post.

Tuesday, January 15, 2013

Double NAT - How to solve it?

Before I going to explain how to solve double NAT problem, I will introduce what is NAT first. Due to the number of IP addresses on internet is limited, NAT (Network Address Translation) was introduced. A router will use only one public IP address (Gateway), however, a network behind NAT is using private IP addresses, which is valid within the router network. To be able to access a network within NAT, port forwarding is required in order to bypass the public IP address with a specific port to a specific private IP address with specific port as well. This scenario represents a single level of NAT, having only one router cover all the entire network. But it often isn't simple like this.

Double NAT is a scenario where multiple routers on network do network address translation. The most common sample is a Cable or DSL modem is connected to a Wi-Fi router. NAT of both modem and router are enabled. Then, computers on the network are connected to the Wi-Fi router. In this scenario, even if port forwarding is setup on the Wi-Fi router, the computer will not be accessible from internet because the Wi-Fi doesn't have a public IP address. It has only a private IP address, which is given from the Cable/DSL modem. There are many solutions to solve this problem, however, there is no silver bullet. It depends on situation which one is suitable.

Possible Solutions: 

1. Setup PPPoE connection between the wireless router and modem 

This is the most robust solution, unfortunately not all ISPs provide enough information for this to be setup easily 

PPPoE can be usually setup in the wireless router's WAN settings. There are usually multiple options to configure the WAN connection of wireless router, amongst which are DHCP and PPPoE. DHCP is no good here, as it results in private IP address assigned to the WiFi router. PPPoE is better, because it bypasses the NAT in the modem, however it might need login and password information which the ISP might not provide.

2. Put the wireless router in bridged mode 

Bridged mode on wireless router means that NAT and DHCP functions on it will be disabled. Some router call it bridged mode, some simply allow you to disable NAT and DHCP. Unfortunately some WiFi routers simply don't support bridged mode at all. 

If you manage to switch router to bridged mode, all port forwarding needs to be configured on the modem (either automatically if it supports NAT-PMP, or manually).

3. Put the wireless router in modem's DMZ 

DMZ (demilitarized zone) is a common feature of router that allow to chose one client to which all traffic is forwarded. If your modem supports DMZ, this might be solution for you: 

1. Find out the WAN address of wireless router. For this you might need to log in to the WiFi router admin interface and look at the Status page (most router's have status pages which show relevant information about the WAN connection). 

2. Log in to the modem web administration interface, find the DMZ settings and put the WiFi router's IP WAN address there. 

Note that with this solution you will still get a double NAT warning in Air Video Server, but if the port forwarding on Wireless router is setup correctly, things should work.

4. Forward the port 45631/TCP in the modem to the router

This solution is similar to [3], except that instead of putting the WiFi router to modem's DMZ only one port is forwarded. 

1. Find out the WAN address of wireless router. For this you might need to log in to the WiFi router admin interface and look at the Status page (most router's have status pages which show relevant information about the WAN connection). 

2. Login in the modem web admin interface and configure port forwarding of port 45631 (protocol TCP) to the address from router's status page.

Note that with this solution you will still get a double NAT warning in Air Video Server.

From mentioned solutions, for me, I prefer to use the first two solutions because they are easy to setup, just setting either a DSL/Cable modem or Wi-Fi router to a bridged mode. The  two nested networks will become one. It is different only in setting DSL/Cable modem or router to a bridged mode is needed to use a Wi-Fi router connecting to ISP using PPPoE with username and password, but setting a Wi-Fi router to a bridged mode, the DSL/Cable modem or router must be able to set port forwarding, which in some routers there is only one direction from in to out, doesn't allow outside network coming in.

Reference: http://inmethod.com/forum/posts/list/908.page -> This thread helps me so much, thanks to him.

Thursday, January 3, 2013

Embedding string base64 image into HTML

Sometimes when we have to deal with dynamic images in web application, we can't just use the link refer to any image because we just want to generate it for temporary purpose. In order to solve this problem, HTML is be able to read an image data in form of base64 string then show an image in the browser.

It's a simple to express an image in string format using the following template:
<img src="data:image/[format];base64,[base64 image string]"/>
Example:
<img src="data:image/png;base64,iVBORw0KGgoAAAANS..."/>
In the next post, I will write about how to get base64 string from an image.

Reference: Embedding Base64 Image Data into a Webpage

Friday, November 30, 2012

Simple HTTP POST Server / Client with Python

Continue from the last post, it's about simple HTTP server with Python. Today, I will explain more about create POST server with Python. From last time to response GET request, we need to override do_GET in class SimpleHTTPRequestHandler. Similarly, to response POST request, we just override do_POST method. However, to receive parameters from POST there are 2 popular formats: url-encode, and multipart as I described in my previous post

In this post I will describe only url-encode. It's like encrypt the data in url format before sending to the server. So, your data will be like "{key1}={value1}&{key2}={value2} ...:". Basically, it's not that difficult with Python because all we need, are already had.

HTTP POST Client:
import urllib, urllib2

uri = 'http://localhost:8000'
name = "Mark"
# Encode data in base64 string
encode = name.encode('base64')
params = { 'name' : encode }
# Pack key-value pairs in form of url-encode format
data = urllib.urlencode(params)

# urlopen with data will use POST method by default
p = urllib2.urlopen(uri, data)
print p.read()
HTTP POST Server:
import SimpleHTTPServer
import SocketServer
import cgi
from base64 import decodestring

# Server port
PORT = 8000

class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  
        def do_POST(self):
                # Use cgi module to retrieve data from POST as a form
                form = cgi.FieldStorage(
                        fp=self.rfile,
                        headers=self.headers,
                        environ={'REQUEST_METHOD':'POST',
                                 'CONTENT_TYPE':self.headers['Content-Type'],
                                 })
                # We can get value from the form key like we did in dictionary class
                encode = form['name'].value
                # Decide the value from base64 string
                decode = decodestring(encode)
                self.wfile.write('Hello, ' + decode + '.')
                
Handler = ServerHandler

# Initialize server object
httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()

Wednesday, November 28, 2012

Simple HTTP Server with Python

To create HTTP server in Python, we need to bind to a port & IP address, listen to that port for responding requests. To do that, we can use built-in module named BaseHTTPServer to handle HTTP requests. The main methods are do_GET and do_HEAD, we will need them to construct our header and body.

Here is a server code:
import SimpleHTTPServer
import SimpleHTTPServer
import SocketServer

# Server port
PORT = 8000

class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

 def _writeheaders(self):
  self.send_response(200)
  self.send_header('Content-type', 'text/html')
  self.end_headers()

 def do_GET(self):
  # Handle GET request
  self._writeheaders()
  self.wfile.write("""
  <html><head><title>Simple Server with Python</title></head>
   <body>
    Hello World!!!!
   </body>
  </html>""")

Handler = ServerHandler

# Initialize server object
httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()
For handling POST request, just create do_POST method in ServerHandler class. I will explain more in the next post. For this post, just want to ground the basic HTTP server knowledge.

References:

Monday, November 26, 2012

HTTP POST data via WebClient and WebRequest

To request HTTP with POST method in .NET, there are 2 classes applicable to do that: WebClient, and WebRequest. I will describe  both ways in post. Normally to send the data back via POST method, there are 2 kinds of content-type (that I know) are url-encode, multipart. These two content types have an effect for the specific format for a receiver and how to construct a form message. In this post I will explain only url-encode. Firstly, we should know how to construct a format. For urlencode format, the format is very similar to querystring format like "{key1}={value1}&{key2}={value2}...". Moreover, we should encode the values like a GET parameter string (not necessary but for some characters, they need to).

To specific content-type for urlencode is set its value to "application/x-www-form-urlencoded".

Example 1: using WebClient
using System.Web;
...
private void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
     // Show a return message when upload is completed
     var result = (string)e.Result;
     MessageBox.Show(result);
}

private void Do_Something()
{
      string name = "Hello";
      string url = "<host ip>";
      var base64 = "name=" + HttpUtility.UrlEncode(result);

      var wc = new WebClient();
      wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
      wc.UploadStringCompleted += wc_UploadStringCompleted;
      wc.UploadStringAsync(new Uri(url), "POST", base64);
}
Example 2: using WebRequest
using System.Net;
...
private void Do_Something()
{
      string name = "Hello";
      string url = "<host ip>";
      var base64 = "name=" + HttpUtility.UrlEncode(result);

      var encode = Encoding.UTF8.GetBytes(base64);

      var request = WebRequest.Create(new Uri(url));
      request.Method = "POST";
      request.ContentType = "application/x-www-form-urlencoded";
      request.ContentLength = encode.Length;
      Stream dataStream = request.GetRequestStream();
      dataStream.Write(encode, 0, encode.Length);
      dataStream.Close();

      using (var response = request.GetResponse())
      {
           using (var reader = new StreamReader(response.GetResponseStream()))
           {
                // Show a response message
                string responseText = reader.ReadToEnd();
                MessageBox.Show(responseText );
            }
      }
}
The different from these 2 methods in my opinion are details for handling data i.e. We need to create delegate function for handling task when uploading is done, but WebRequest doesn't need to. Moreoever, WebClient has higher level of data sending compared to WebRequest. WebRequest need to pack data into byte array, but WebClient can send them as a pack of string directly.

Friday, November 23, 2012

What the different between Web Browser, Web Client, WebRequest, WebResponse

I found the answer from stack overflow. He said as the following description:
WebBrowser is actually in the System.Windows.Forms namespace and is a visual control that you can add to a form. It is primarily a wrapper around the Internet Explorer browser (MSHTML). It allows you to easily display and interact programmatically with a web page. You call the Navigate method passing a web URL, wait for it to complete downloading and display and then interact with the page using the object model it provides.

HttpWebRequest is a concrete class that allows you to request in code any sort of file over HTTP. You usually receive it as a stream of bytes. What you do with it after that is up to your application.

HttpWebResponse allows you to process the response from a web server that was previously requested using HttpWebRequest.

WebRequest and WebResponse are the abstract base classes that the HttpWebRequest and HttpWebResponse inherit from. You can't create these directly. Other classes that inherit from these include Ftp and File classes.

WebClient I have always seen as a nice helper class that provides simpler ways to, for example, download or upload a file from a web url. (eg DownloadFile and DownloadString methods). I have heard that it actually uses HttpWebRequest / HttpWebResponse behind the scenes for certain methods.

If you need more fine grained control over web requests and responses, HttpWebRequest / HttpWebResponse are probably the way to go. Otherwise WebClient is generally simpler and will do the job.
In my opinion, I prefer to use WebClient because it's much more higher level, and easy to use in case we need to specific setting parameters. However, if I only use it for crawl data, mostly I just use WebRequest because it's short, and simple don't need to have delegate for async function.

Reference: http://stackoverflow.com/questions/1780679/net-webbrowser-webclient-webrequest-httpwebrequest-argh

Wednesday, November 14, 2012

Using the aria-labelledby attribute

The aria-labelledby attribute can be used for indicating label for an object which can be a list of id (separated by space). It is useful  for rich internet applications to describe objects. There are 2 sources, and 1 example websites that may helpful.