4

I have a C# application that communicates with a PHP-based SOAP web service for updates and licensing.

I am now working on a feedback system for users to submit errors and tracelogs automatically through the software. Based on a previous question I posted, I felt that a web service would be the best way to do it (most likely to work properly with least configuration).

My current thought is to use .NET built-in gzip compression to compress the text file, convert to base64, send to the web-service, and have the PHP script convert to binary and uncompress the data.

Can PHP decompress data compressed with GZipStream, and if so, how?

Chris Thompson
  • 16,203
  • 9
  • 45
  • 62

6 Answers6

7

I actually tried this. GZipStream doesn't work. On the other hand, compressing with DeflateStream on .NET side and decompressing with gzinflate on PHP side do work. Your mileage may vary...

sanxiyn
  • 3,648
  • 1
  • 19
  • 15
  • I just prototyped this solution and it works. Now I just have to deal with PHP memory allocation errors from decompressing and escaping large files. – Chris Thompson May 26 '09 at 03:48
1

If the http-level libraries implements it (Both client and server), http has support for gzip-compression, in which case there would be no reason to manually compress anything. You should check if this is already happening before you venture any further.

troelskn
  • 115,121
  • 27
  • 131
  • 155
  • 1
    Does that work for the client sending data? I've done gzip encoding from the server to the client, but not from the client to the server. – Chris Thompson May 25 '09 at 16:15
  • I'm quite sure that it's valid according to HTTP. Whether it's supported by the implementations is another matter though. Still - I think it's worth to investigate. – troelskn May 25 '09 at 16:16
0

I was able to demo this with Gzip on C# and PHP.

Gzip Compressing in C#:

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

public class Program {
    public static void Main() {
        string s = "Hi!!";

        byte[] byteArray = Encoding.UTF8.GetBytes(s);
        byte[] b2 = Compress(byteArray);

        Console.WriteLine(System.Convert.ToBase64String(b2));
    }

    public static byte[] Compress(byte[] bytes) {
        using (var memoryStream = new MemoryStream()) {
            using (var gzipStream = new GZipStream(memoryStream, CompressionLevel.Optimal)) {
                gzipStream.Write(bytes, 0, bytes.Length);
            }
            return memoryStream.ToArray();
        }
    }

    public static byte[] Decompress(byte[] bytes) {
        using (var memoryStream = new MemoryStream(bytes)) {

            using (var outputStream = new MemoryStream()) {
                using (var decompressStream = new GZipStream(memoryStream, CompressionMode.Decompress)) {
                    decompressStream.CopyTo(outputStream);
                }
                return outputStream.ToArray();
            }
        }
    }
}

the code above prints the base64 encoded compressed string which is H4sIAAAAAAAEAPPIVFQEANxaFPgEAAAA for the Hi!! input.

Here's the code to decompress in PHP:

echo gzdecode(base64_decode('H4sIAAAAAAAEAPPIVFQEANxaFPgEAAAA'));
MSE
  • 625
  • 9
  • 19
0

Yes, PHP can decompress GZIP compressed strings, with or without headers.

  • gzdecode for GZIP file format (ie, compatible with gzip)
  • gzinflate for "raw" DEFLATE format
  • gzuncompress for ZLIB format (GZIP format without some header info)

I don't know for sure which one you'd want as I'm unfamiliar with .NET GZipStream. It sounds a little like gzuncompress, as the ZLIB format is kind of a "streaming" format, but try all three.

thomasrutter
  • 114,488
  • 30
  • 148
  • 167
  • 2
    For future reference: gzinflate is the method that will decompress GZipStream compressed data. – Chris Thompson Jan 14 '11 at 09:17
  • 1
    @ChrisThompson What? No. `gzdecode()` will decompress `GZipStream` compressed data. The only way to use `gzinflate()` would be if you stripped the gzip header and trailer from the output of `GZipStream`. – Mark Adler Sep 29 '22 at 16:34
0

Since the server is accepting web requests you really should be checking the HTTP headers to determine if any client accepts GZIP encoding rather than just guessing and gzipping each and every time.

If the PHP client can do gzip itll set the header and your code will then react according and do the right thing. Assuming or guessing is a poor choice when the facility is provided for your code to learn the capabilities of the client.

mP.
  • 18,002
  • 10
  • 71
  • 105
  • I don't think this applies. The client is the C# app, the server is PHP based. The client is initiating the connection to the server, so the headers would be generated by the client (C#) app, not the server. – Chris Thompson May 25 '09 at 07:52
  • @Chris You missed the point, the client needs to tell the server what and how it wants something. Just like it uses a URL to identify a resource, the reason for headers is to include a variety of meta data including what encoding formats the client wishes to recieve. You have mis understood the entire reasoning behind headers, they allow a client to send extra info in which the server can tailor the response. – mP. May 26 '09 at 02:47
  • For instance theres a header that one can check to query about a users preferred languages with weights informing you what languages they want. Your server stuff should naturally check this and were possible tailor your response. If your writing an international app, then it makes sense to check and cater for this... not everyone speaks English and sending English when the ser might want Spanish or German would be silly. – mP. May 26 '09 at 02:49
0

I wrote an article I recently posted that shows how to compress/decompress in C#. I used it for almost the same scenario. I wanted to transfer log files from the client to the server and they were often quite large. However in my case my webservice was running in .NET so I could use the decompress method. But looks like PHP does support a method called gzdecode that would work.

http://coding.infoconex.com/post/2009/05/Compress-and-Decompress-using-net-framework-and-built-in-GZipStream.aspx

Jim Scott
  • 2,493
  • 1
  • 18
  • 16