none
TCP Socket with HTTP POST RRS feed

  • Question

  • My client requires the following mode of communication

    1. Your software opens a socket from your client platform to connect our server platform.
    2. Our server will respond by starting the “keep alive” dialog.
    3. Your software will send an X12 transmission packet with a request
    4. Our server will check the request and respond with a response.

    This is how  a typical transmission looks like

    Request

    POST /OKMMISPOS HTTP/5.1
    Content-Length: 521

    <Body of the request>

    Response

    HTTP/5.1 200 OK
    Content-Length: 448

    <Body of the response>

    This is all the information that was provided to me. There is no URL, Host Header for the Request. This connection is established using a tunnel. So we have a source IP:Port connecting to their destination IP:Port. I am using to connect to our source and then send a request to their IP:Port. This is all the information they want in the request. No URl's, no host, port. Only  what is listed above.

    So here's how I went about doing this.

       private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    //create a new client socket ...
            // This will be the destination servers IP/Port
               string szIPSelected = "1:2:43:1";
               int szPort = 00000;
               Socket m_socClient = new Socket    (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
               System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(szIPSelected , szPort);
              m_socClient.Connect(remoteEndPoint);
               if (m_socClient.Connected)
                {
                      
                        
            string resource= "/OKMMISPOS";                       
    var header = String.Format("POST {0} HTTP/5.1 " + Environment.NewLine, resource);
            String body = "Body of my request";
            byte[] bodyBytes = Encoding.ASCII.GetBytes(body);
                header += "Content-Length: " +  (bodyBytes.Length) + Environment.NewLine + Environment.NewLine;
            string request = String.Concat(header, body);
            byte[] bytesToSend = Encoding.ASCII.GetBytes(request);
           byteCount = m_socClient.Send(bytesToSend, SocketFlags.None);
    
             toolStripStatusLabel1.Text = "Sending  Request to  " + szIPSelected + ":" + szPort;
                        statusStrip1.Refresh();
                        byte[] bytesReceived = new byte[1024];
                        byteCount = m_socClient.Receive(bytesReceived, SocketFlags.None);
                        txtResponse271.Text =
                               Encoding.ASCII.GetString(bytesReceived);
                        m_socClient.Disconnect(false);
                        m_socClient.Close();
                    }
                }
                catch (Exception se)
                {
                    MessageBox.Show(se.Message);
                    m_socClient.Close();
                    MessageBox.Show(se.Message);
                }
                finally
                {
                     m_socClient.Disconnect(false);
                    m_socClient.Close();
                }
    
    
                
    
                }

    I am using a Socket and connecting it to a endpoint. Sending the entire reques by appending the required 2 lines in the Header including the content length. The socke sends a message, receives it.

    THis seems to be good. Although I a getting a HTTP bad request.

    POST /OKMMISPOS HTTP/5.1
    Content-Length: 484

    RequestBody

    Response;

    HTTP/1.1 400 Bad Request
    Content-Length: 484

    ResponseBody

    This is how my request and response  looks like.

    Wireshark didn't give me a lot of info except protocols and HTTP Bad request. Please suggest.

    Thank you

    sun


    sunDisplay

    Tuesday, July 23, 2013 4:47 AM

Answers

  • I've never been successful in getting a proper response even with the Composer tab on Fiddler. Used the Raw tab instead of  'Parsed' tab since my request needs HTTP 5.1 and does not have a HOSTT. They've built a tunnel from our IP:port to their IP:port. So this is performed via a tunnel. May be this is why they don't need a HOST in the Header.

     

    This is how I am caluculating the content length

      string resource = "/OKMMISPOS";
      var header = String.Format("POST {0} HTTP/5.1 " + Environment.NewLine, resource);
     String body = "My content String";
     byte[] bodyBytes = Encoding.ASCII.GetBytes(body);
      header += "Content-Length: " + (bodyBytes.Length) + Environment.NewLine + Environment.NewLine;
     string request = String.Concat(header, body);
     byte[] bytesToSend = Encoding.ASCII.GetBytes(request);
     byteCount = m_socClient.Send(bytesToSend, SocketFlags.None)

    This is how I am calculating the content length. So for this example,  

    (My content String).length = 17.

    That's what they've asked me to do. I tried that and also Encoding.ASCII.GetBytes("My content String");

    Same HTTP 1.1 bad request. Sample response from them indicated it would be HTTP 5.1 instead of 1.1

    This is really weird.

     


    sunDisplay

    Tuesday, July 23, 2013 11:04 AM
  • Well, I don't see what can I suggest. Obviously the reply they're sending doesn't match their sample.

    Your code appears to be correct, though a bit convoluted. I'll note that there appears to be a space after 5.1 on this line:

    String.Format("POST {0} HTTP/5.1 " + Environment.NewLine, resource);

    Try removing that space if it's really there.

    Another thing you could try is to replace Environment.NewLine with "\n". Normally HTTP uses "\r\n" and what's exactly what Environment.NewLine is (at least on Windows) but who knows, maybe their "HTTP" only deals with "\n".

    Tuesday, July 23, 2013 11:23 AM
    Moderator

All replies

  • That 5.1 after HTTP is weird. I don't know if they're using some kind of improvised HTTP server but even if they do that it wouldn't make sense to come up with some weird HTTP version number. Besides, their response uses 1.1 instead of 5.1. Try changing 5 to 1 and see if it works.
    Tuesday, July 23, 2013 4:57 AM
    Moderator
  • The contents length may also be wrong.  I would start by trying using an IE application manually and capture the results with wireshark, then compare the IE results with your VS application.  You are mssing a number of headers in your request that are normally sent and the Server may need these missing headers.  The IE results will show you these missing headers.

    jdweng

    Tuesday, July 23, 2013 5:40 AM
  • Hi Mike,

     
    I've contacted them using this. They asked me to use HTTP 5.1. They get a bad compliance error when changed to 1.1

    I have a sample response in the question. It is supposed to come back as HTTP/5.1_200_OK.

    Thank you

    Sun


    sunDisplay

    Tuesday, July 23, 2013 10:49 AM
  • "They asked me to use HTTP 5.1. They get a bad compliance error when changed to 1.1"

    That's mind-boggling. They make up something that looks like HTTP but it isn't and then they pull out a version number out of a hat. IMO, whatever problem you are having with this you should take it to them, nobody can guess what weird requirements their "HTTP" server has.

    "I have a sample response in the question. It is supposed to come back as HTTP/5.1_200_OK."

    But in your previous post you're showing a response with 1.1. Maybe you're accidentally connecting to a different web server?

    Tuesday, July 23, 2013 10:59 AM
    Moderator
  • I've never been successful in getting a proper response even with the Composer tab on Fiddler. Used the Raw tab instead of  'Parsed' tab since my request needs HTTP 5.1 and does not have a HOSTT. They've built a tunnel from our IP:port to their IP:port. So this is performed via a tunnel. May be this is why they don't need a HOST in the Header.

     

    This is how I am caluculating the content length

      string resource = "/OKMMISPOS";
      var header = String.Format("POST {0} HTTP/5.1 " + Environment.NewLine, resource);
     String body = "My content String";
     byte[] bodyBytes = Encoding.ASCII.GetBytes(body);
      header += "Content-Length: " + (bodyBytes.Length) + Environment.NewLine + Environment.NewLine;
     string request = String.Concat(header, body);
     byte[] bytesToSend = Encoding.ASCII.GetBytes(request);
     byteCount = m_socClient.Send(bytesToSend, SocketFlags.None)

    This is how I am calculating the content length. So for this example,  

    (My content String).length = 17.

    That's what they've asked me to do. I tried that and also Encoding.ASCII.GetBytes("My content String");

    Same HTTP 1.1 bad request. Sample response from them indicated it would be HTTP 5.1 instead of 1.1

    This is really weird.

     


    sunDisplay

    Tuesday, July 23, 2013 11:04 AM
  • This is a tunnel. I have to look to into that different webserver issue. I am assuming that I am connecting to the correct server. This request will not connect if that was the case. Socket connection is being established. Tunnel was built from our IP:port to their IP:port.
    Sample response Header:  HTTP/5.1_200_OK
    Content-Length:_448
     
    My response Header
     
    HTTP 1.1 Bad request
    Please suggest

    sunDisplay

    Tuesday, July 23, 2013 11:15 AM
  • Well, I don't see what can I suggest. Obviously the reply they're sending doesn't match their sample.

    Your code appears to be correct, though a bit convoluted. I'll note that there appears to be a space after 5.1 on this line:

    String.Format("POST {0} HTTP/5.1 " + Environment.NewLine, resource);

    Try removing that space if it's really there.

    Another thing you could try is to replace Environment.NewLine with "\n". Normally HTTP uses "\r\n" and what's exactly what Environment.NewLine is (at least on Windows) but who knows, maybe their "HTTP" only deals with "\n".

    Tuesday, July 23, 2013 11:23 AM
    Moderator