SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 26
  1. #1
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PDF Download Problem

    Hi Guys!

    I have created a script which uploads PDF's into a database and stored as a blob. I have also created a download script to download the PDF. Both scripts work fine on my site from admin (mysitecom/cms). I am using exactly the same download function from the user side (wordpress site), however I get an error in my browser when I try and download the PDF from the user side. The error is the same in Firefox, IE and Safari.

    The error says:

    Code:
    The file Kirk-7.pdf could not be opened.
    
    It may be damaged or use a file format that Preview doesnt recognize.
    Here is my PHP download script:

    PHP Code:
    function DownloadPDF(){
            
    $result $this->dbh->getRow("select * from pdfs where id='".mysql_real_escape_string($_GET['pdfid'])."'"DB_FETCHMODE_ASSOC);
            
            if(!empty(
    $result['id'])){
                
    header("Content-length: ".$result['pdf_size']);
                
    header("Content-type: application/pdf");
                
    header('Content-Disposition: attachment; filename="'.$result['pdf_name'].'"');
                echo 
    $result['pdf_content'];
            } else {
                
    $Error['error'] = "You do not have any PDF's available to download.";
                return 
    $Error;
            }
        } 
    Am I missing something?

    Thanks.

  2. #2
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Guys,

    I done a print_r() on the $result and it seems the pdf content is getting cut off (i.e. the data is missing which is why we are getting a corrupted error.

    Any idea why this would happen?

  3. #3
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Does the full content exist in the database?
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  4. #4
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    Does the full content exist in the database?
    Yes the full content exists in the database (100%).

  5. #5
    SitePoint Wizard bronze trophy Immerse's Avatar
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    1,661
    Mentioned
    7 Post(s)
    Tagged
    1 Thread(s)
    Does $result['pdf_size'] equal strlen($result['pdf_content']) ?

    Maybe the pdf_size is smaller than the actual size of the pdf's content, causing the browser to close the connection after downloading pdf_size data.

  6. #6
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Immerse View Post
    Does $result['pdf_size'] equal strlen($result['pdf_content']) ?

    Maybe the pdf_size is smaller than the actual size of the pdf's content, causing the browser to close the connection after downloading pdf_size data.
    Yes both of the sizes correlate to each other - 44838. Could it be something to do with the charset?

  7. #7
    SitePoint Wizard bronze trophy Immerse's Avatar
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    1,661
    Mentioned
    7 Post(s)
    Tagged
    1 Thread(s)
    Hmm, it could be, actually.

    If the file is multibyte, then strlen might return an incorrect value.
    Try using mb_strlen.

    Something else you could try, just to find out what's going on, is to write a script that will write out the PDF file on disk somewhere, download that file through FTP/ SSH/ whatever and see how large it is, and then compare that to the files you've downloaded through the web interface.

  8. #8
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Immerse View Post
    Hmm, it could be, actually.

    If the file is multibyte, then strlen might return an incorrect value.
    Try using mb_strlen.

    Something else you could try, just to find out what's going on, is to write a script that will write out the PDF file on disk somewhere, download that file through FTP/ SSH/ whatever and see how large it is, and then compare that to the files you've downloaded through the web interface.
    Ahhhaaaa....now when I do mb_strlen($result['pdf_content']) I get 32281 as opposed to the value I posted yesterday.

    What does this mean?

  9. #9
    SitePoint Wizard bronze trophy Immerse's Avatar
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    1,661
    Mentioned
    7 Post(s)
    Tagged
    1 Thread(s)
    Not sure actually
    Sorry, that's not very helpful, is it.

    What happens if you try to download the file without sending a Content-Length header?
    (I know, it's bad practice, but it's just to see what's going on so we can figure out what the actual content length is).

  10. #10
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:

    Lovin' the thought processes Immerse!
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  11. #11
    SitePoint Zealot
    Join Date
    Jun 2010
    Location
    Arizona
    Posts
    109
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    strlen() should return the binary length of whatever data is input. In general, I don't output a 'Content-Length' header because it isn't recommended - try removing that. You should check your file and make sure that you don't have a Unicode header being prepended by your editor when you save and also make sure that there are no extra characters being output (e.g. even a single whitespace character after the '?>' can do weird stuff). Might also want to check that the data being output is actually a PDF (e.g. no errors/warnings or other bad data) by dropping the other two header() statements to test that possibility.
    Thomas Hruska

    Single Sign-On Server/Client - The PHP login system that rocks.

  12. #12
    SitePoint Wizard bronze trophy Immerse's Avatar
    Join Date
    Mar 2006
    Location
    Netherlands
    Posts
    1,661
    Mentioned
    7 Post(s)
    Tagged
    1 Thread(s)
    Off Topic:


    Yeah, sometimes my thoughts are actually organised properly, usually they just pop in and out of my as I post them


    Quote Originally Posted by AnthonySterling View Post
    Off Topic:

    Lovin' the thought processes Immerse!

  13. #13
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Immerse View Post
    Not sure actually
    Sorry, that's not very helpful, is it.

    What happens if you try to download the file without sending a Content-Length header?
    (I know, it's bad practice, but it's just to see what's going on so we can figure out what the actual content length is).
    I tried downloading without a Content-Length but get the same error.

    It's so strange, the exact same function works fine from admin, but in the client area (which is run by Wordpress) the pdf_content field is cut off. Would there be anything inside wordpress that could cause this?

  14. #14
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here is the PDF content from admin (this works):
    Code:
    %PDF-1.3 % 3 0 obj << /Linearized 1 /O 5 /H [ 797 164 ] /L 6365 /E 5955 /N 1 /T 6188 >> endobj xref 3 20 0000000016 00000 n 0000000744 00000 n 0000000961 00000 n 0000001112 00000 n 0000001291 00000 n 0000001835 00000 n 0000002215 00000 n 0000002402 00000 n 0000002593 00000 n 0000002773 00000 n 0000004378 00000 n 0000004488 00000 n 0000004770 00000 n 0000004839 00000 n 0000005020 00000 n 0000005195 00000 n 0000005401 00000 n 0000005813 00000 n 0000000797 00000 n 0000000941 00000 n trailer << /Size 23 /Info 2 0 R /Root 4 0 R /Prev 6179 /ID[<4dc91a1875a6d707aec203bb021c93a0><4dc91a1875a6d707aec203bb021c93a0>] >> startxref 0 %%EOF 4 0 obj << /Type /Catalog /Pages 1 0 R >> endobj 21 0 obj << /S 36 /Filter /FlateDecode /Length 22 0 R >> stream Hb``b``ea'lJ aWn.o'kc`Ua`g䵃  endstream endobj 22 0 obj 60 endobj 5 0 obj << /Type /Page /Parent 1 0 R /Resources 6 0 R /Contents 12 0 R /MediaBox [ 0 0 595 842 ] /CropBox [ 0 0 595 842 ] /Rotate 0 >> endobj 6 0 obj << /ProcSet [ /PDF /Text ] /Font << /F2 13 0 R /TT2 8 0 R /TT4 7 0 R /TT6 17 0 R /TT8 19 0 R >> /ExtGState << /GS1 20 0 R >> /ColorSpace << /Cs5 11 0 R >> >> endobj 7 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 174 /Widths [ 250 0 0 0 0 0 0 180 333 333 0 0 250 0 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 667 722 0 556 0 0 0 0 0 0 0 0 0 556 0 667 0 611 0 0 944 0 0 0 0 0 0 0 0 0 444 500 444 500 444 333 500 500 278 0 0 278 778 500 500 500 0 333 389 278 500 500 722 0 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 760 ] /Encoding /WinAnsiEncoding /BaseFont /TimesNewRomanPSMT /FontDescriptor 10 0 R >> endobj 8 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 116 /Widths [ 278 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 722 0 0 722 0 611 0 0 0 0 0 0 0 0 0 667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 611 556 611 556 0 0 0 278 0 0 278 0 0 611 0 0 389 556 333 ] /Encoding /WinAnsiEncoding /BaseFont /Arial-BoldMT /FontDescriptor 9 0 R >> endobj 9 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 32 /FontBBox [ -628 -376 2034 1048 ] /FontName /Arial-BoldMT /ItalicAngle 0 /StemV 133 >> endobj 10 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 34 /FontBBox [ -568 -307 2028 1007 ] /FontName /TimesNewRomanPSMT /ItalicAngle 0 /StemV 0 >> endobj 11 0 obj [ /CalRGB << /WhitePoint [ 0.9505 1 1.089 ] /Gamma [ 2.22221 2.22221 2.22221 ] /Matrix [ 0.4124 0.2126 0.0193 0.3576 0.71519 0.1192 0.1805 0.0722 0.9505 ] >> ] endobj 12 0 obj << /Length 1530 /Filter /FlateDecode >> stream HWKo6Fs[t)b+ n$*dSi{- ,ZPr曙o?tۮ aqR@2<q7m	c	as/)<6$ 64^6(MLѶSevmJChZ 6Sk  w{?D~~&c& fдqrY(:$ !0G~7k`P$np}TƹEZ[g&K'2=,!9-^FxU&QȽ^Q/SbśE[1IQT_u-qk,Ya}I#pwY GsȉpFj	*08,sﲔqP+NEf#_Z򥥚sBh[2 C8YNbQ?0k+W& 'PjQ̐ܛeZfZ8́]F/{"MVK az2S>Wega$Y+RH}uPWP\TxpWHV%sE __4zS= ^aIp (0 A#HOѶ@#f n&*I	!@0bNq$`+Ʀ>ӤDO;FN4^1; s}M{:LrdN"dLQt O  rhdbbTp*/qEUCv#^=2`#F`E&((,2?Q	ӶWIߘ@BcdRM{\>(/.*rQ?\NHD/hZW3YsU5Dj/.NT[QE&ƿ3	QQ?#?5ߋ6iݦЦmt7q1ڞ"/Ȇ)e z( kPq.]4oCDIlAqz+la{g,~..Cypd+	 L0 4¾L*7ov4giPeD%]lY	g'դJI ^X,GM)-,H j*>1 36f`Zpdj@B6M䈈۳AAIwVn?~-J?3~vFn4/l*,S`dDA .Y*ysDOtAaD%w ]sh>7IN~S:IT8sO驽*y,`:+a)e*<&CFRͣ_yi>dU}p_D]F ]c4K]heQxsWā?v  endstream endobj 13 0 obj << /Type /Font /Subtype /Type1 /Encoding 15 0 R /BaseFont /Symbol /ToUnicode 14 0 R >> endobj 14 0 obj << /Filter /FlateDecode /Length 208 >> stream HT0>GCUX:# iVз')Kӝ-͡!@\ة4&V (AnJ"< *(gشsoAY#`s+8h'hP (IZ.b5tG/ʋ]!Ve^u[M1ֲ(e0ߋxezKCi? endstream endobj 15 0 obj << /Type /Encoding /Differences [ 1 /bullet ] >> endobj 16 0 obj << /Type /FontDescriptor /Ascent 905 /CapHeight 0 /Descent -211 /Flags 32 /FontBBox [ -665 -325 2028 1037 ] /FontName /ArialMT /ItalicAngle 0 /StemV 0 >> endobj 17 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 32 /Widths [ 278 ] /Encoding /WinAnsiEncoding /BaseFont /ArialMT /FontDescriptor 16 0 R >> endobj 18 0 obj << /Type /FontDescriptor /Ascent 891 /CapHeight 0 /Descent -216 /Flags 98 /FontBBox [ -547 -307 1206 1032 ] /FontName /TimesNewRomanPS-BoldItalicMT /ItalicAngle -15 /StemV 133 >> endobj 19 0 obj << /Type /Font /Subtype /TrueType /FirstChar 32 /LastChar 121 /Widths [ 250 0 0 0 0 0 0 0 0 0 0 0 250 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0 444 0 444 0 0 556 278 0 0 278 0 556 500 500 0 389 389 278 0 0 667 500 444 ] /Encoding /WinAnsiEncoding /BaseFont /TimesNewRomanPS-BoldItalicMT /FontDescriptor 18 0 R >> endobj 20 0 obj << /Type /ExtGState /SA false /SM 0.02 /TR /Identity >> endobj 1 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 2 0 obj << /ModDate (D:20000629102135+11'00') /CreationDate (D:20000629102108+11'00') /Title (This is a test PDF file) /Author (cdaily) /Creator (Microsoft Word 8.0) /Producer (Acrobat Distiller 4.0 for Windows) >> endobj xref 0 3 0000000000 65535 f 0000005891 00000 n 0000005955 00000 n trailer << /Size 3 /ID[<4dc91a1875a6d707aec203bb021c93a0><4dc91a1875a6d707aec203bb021c93a0>] >> startxref 173 %%EOF
    Here is the PDF content from client area (corrupt download):
    Code:
    %PDF-1.3 %���� 3 0 obj << /Linearized 1 /O 5 /H [ 797 164 ] /L 6365 /E 5955 /N 1 /T 6188 >> endobj xref 3 20 0000000016 00000 n 0000000744 00000 n 0000000961 00000 n 0000001112 00000 n 0000001291 00000 n 0000001835 00000 n 0000002215 00000 n 0000002402 00000 n 0000002593 00000 n 0000002773 00000 n 0000004378 00000 n 0000004488 00000 n 0000004770 00000 n 0000004839 00000 n 0000005020 00000 n 0000005195 00000 n 0000005401 00000 n 0000005813 00000 n 0000000797 00000 n 0000000941 00000 n trailer << /Size 23 /Info 2 0 R /Root 4 0 R /Prev 6179 /ID[<4dc91a1875a6d707aec203bb021c93a0><4dc91a1875a6d707aec203bb021c93a0>] >> startxref 0 %%EOF 4 0 obj << /Type /Catalog /Pages 1 0 R >> endobj 21 0 obj << /S 36 /Filter /FlateDecode /Length 22 0 R >> stream H�b``b``�e

  15. #15
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Compare the headers sent using something like LiveHTTPHeaders.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  16. #16
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    Compare the headers sent using something like LiveHTTPHeaders.
    Here are the results from the LiveHTTPHeaders, response headers only.

    Admin (download OK):

    Code:
    HTTP/1.1 200 OK
    Date: Mon, 06 Dec 2010 11:02:15 GMT
    Server: Apache
    X-Powered-By: PHP/5.2.14
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Content-Length: 3488
    Keep-Alive: timeout=10, max=30
    Connection: Keep-Alive
    Content-Type: text/html
    Client area (download error):
    Code:
    HTTP/1.1 200 OK
    Date: Mon, 06 Dec 2010 11:01:19 GMT
    Server: Apache
    X-Powered-By: PHP/5.2.14
    X-Pingback: http://www.hiddenurl.com/xmlrpc.php
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Content-Length: 392
    Keep-Alive: timeout=10, max=30
    Connection: Keep-Alive
    Content-Type: text/html; charset=UTF-8

  17. #17
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    You have no charset in the admin side...

    Can you compare the headers when downloading a PDF?
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  18. #18
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    You have no charset in the admin side...

    Can you compare the headers when downloading a PDF?
    How can I compare the headers when downloading a PDF? The outputs posted above are just from the page which does a print_r of the pdf content.

  19. #19
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Exactly the same way, just do whatever you do to download a PDF and paste the headers here.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  20. #20
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    Exactly the same way, just do whatever you do to download a PDF and paste the headers here.
    When I download a PDF a dialog box just pops up and I am asked to save or open the file. Im not sure how to check the headers on this dialog box...

  21. #21
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    The dialogue box is a by product of the headers, they're still there, open LiveHTTPHeaders in the sidebar of FireFox and you'll see 'em.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  22. #22
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AnthonySterling View Post
    The dialogue box is a by product of the headers, they're still there, open LiveHTTPHeaders in the sidebar of FireFox and you'll see 'em.

    Okay thanks, here are the results:

    Admin:
    Code:
    HTTP/1.1 200 OK
    Date: Mon, 06 Dec 2010 11:48:07 GMT
    Server: Apache
    X-Powered-By: PHP/5.2.14
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Content-Disposition: attachment; filename="Hello.pdf"
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Content-Length: 3488
    Keep-Alive: timeout=10, max=30
    Connection: Keep-Alive
    Content-Type: application/pdf
    Client:
    Code:
    HTTP/1.1 200 OK
    Date: Mon, 06 Dec 2010 11:46:51 GMT
    Server: Apache
    X-Powered-By: PHP/5.2.14
    X-Pingback: http://www.davisinv.com/xmlrpc.php
    Content-Disposition: attachment; filename="Hello.pdf"
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Content-Length: 392
    Keep-Alive: timeout=10, max=30
    Connection: Keep-Alive
    Content-Type: application/pdf

  23. #23
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Even when I remove the Content-Length header from my code, it still appears as "Content-Length: 392" on the response header (client side)..

  24. #24
    SitePoint Wizard Zaggs's Avatar
    Join Date
    Feb 2005
    Posts
    1,048
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Any idea guys? Thanks..

  25. #25
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    I'm all out.

    The headers are identical, barring the content-length, so it's definitely down to the retrieval of the PDF content I'd say.

    Are you using a different method of obtaining the source data? What about output buffering, could this be in play?
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •