- Portals
- The Current Year
- ED in the News
- Admins
- Help ED Rebuild
- Archive
- ED Bookmarklet
- Donate Bitcoin
Contact an admin on Discord or EDF if you want an account. Also fuck bots.
Gopher protocol: Difference between revisions
Pouncing2957 (talk | contribs) No edit summary Tags: Manual revert Reverted |
m Reverted edit by Pouncing2957 (talk) to last revision by HellenicTrapstar Tag: Rollback |
||
Line 1: | Line 1: | ||
[[ | [[Image:gopherprotocol.gif|thumb|right|250px|Gopher Protocol faggot gopher]] | ||
Gopher protocol is another protocol as it can be http or ftp. Its from the 90s, so only [[Oldfag|oldfags]] could know about it. Its more web 1.0 than [[Usenet]] or [[IRC]]. At the present is nearly dead, but there are [[Aspies|some people]] still using it. | |||
== What is it? == | |||
The Gopher protocol is a TCP/IP application layer protocol designed for distributing, searching, and retrieving documents over the Internet. The Gopher protocol was strongly oriented towards a menu-document design and presented an alternative to the World Wide Web in its early stages, but ultimately HTTP became the dominant protocol. The Gopher ecosystem is often regarded as the effective predecessor of the World Wide Web. | |||
The protocol was invented by a team led by [[CSIII|Mark P. McCahill]] at the University of Minnesota. It offers some features not natively supported by the Web and imposes a much stronger hierarchy [[Botnet|on information stored on it]]. Its text menu interface is well-suited to computing environments that rely heavily on remote text-oriented computer terminals, which were still common at the time of its creation in 1991, and the simplicity of its protocol facilitated a wide variety of client implementations. More recent Gopher revisions and graphical clients added support for multimedia. Gopher was preferred by many network administrators for using fewer network resources than Web services. | |||
Gopher's hierarchical structure provided a platform for the first large-scale electronic library connections. Gopher has been described by some enthusiasts as "faster and more efficient and so much more organised" than today's Web services. The Gopher protocol is still in use by [[aspies|enthusiasts]], and a small population of actively maintained servers remain although it has been almost entirely supplanted by the Web. | |||
== What can you find on Gopher? == | |||
*ASCII pr0n | |||
*ASCII pr0n | |||
*Ancient web sites | |||
*Archives of all kind | |||
*Faggots | |||
*ASCII pr0n | |||
*Gopherchan | |||
== How to access Gopher sites? == | |||
You need a browser compatible with gopher protocol, of the main browsers the only one that supports it is [[Firefox|Mozilla Firefox]] and its forks by installing an addon called OverbiteFF. Once you install it you can access a bigger ammount of the net, since search engines dont index gopher sites, so its the best place to hide something online apart from local servers or in Onionland. | |||
== How to browse them? == | |||
Do I need to explain this???? If you cant navigate properly on gopher sites [[GTFO]] of the internet. | |||
== Gopher sites == | |||
*[gopher://gopher.floodgap.com/1/world Veronica2 Gopher search engine] | |||
*[gopher://port70.net/1chan Gopherchan] | |||
*[gopher://gopher.floodgap.com/1/new/ Some of the most modern gopher sites] | |||
*[gopher://gopher.floodgap.com/1/fun/xkcd xkcd] | |||
*[gopher://gopher.floodgap.com/7/fun/figletgw ASCII text maker] | |||
*[gopher://gopher.viste.fr/1/ascii-art/ A huge ASCII art library] | |||
NOTE: there are more | |||
== Gopherchan == | |||
[[Image:1changopher.jpg|thumb|right|250px|Gopherchan index]] | |||
Gopherchan is probably the most web 1.0 chan out there, its also one of the smallests, it only has 2 boards: /b/ and /paste/ and to be able to post on it you need to use the following [[python]] file as explained: | |||
{{frame|{{story|<pre style="border:none; background:none;"> | |||
#!/usr/bin/env python | |||
# client configuration | |||
nickname = 'anon' | |||
delpass = 'lofasz' | |||
handler = 'http://port70.net/cgi/post.cgi' | |||
editor = 'vim "+set tw=70" -c startinsert' | |||
# | |||
# below, the urllib2_file library is embedded | |||
# got it from: http://fabien.seisen.org/python/urllib2_multipart.html | |||
# | |||
############################# | |||
# | |||
# Version: 0.2.0 | |||
# - UTF-8 filenames are now allowed (Eli Golovinsky)<br/> | |||
# - File object is no more mandatory, Object only needs to have seek() read() attributes (Eli Golovinsky)<br/> | |||
# | |||
# Version: 0.1.0 | |||
# - upload is now done with chunks (Adam Ambrose) | |||
# | |||
# Version: older | |||
# THANKS TO: | |||
# bug fix: kosh @T aesaeion.com | |||
# HTTPS support : Ryan Grow <ryangrow @T yahoo.com> | |||
# Copyright (C) 2004,2005,2006 Fabien SEISEN | |||
# | |||
# This library is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU Lesser General Public | |||
# License as published by the Free Software Foundation; either | |||
# version 2.1 of the License, or (at your option) any later version. | |||
# | |||
# This library is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
# Lesser General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU Lesser General Public | |||
# License along with this library; if not, write to the Free Software | |||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
# | |||
# you can contact me at: <[email protected]> | |||
# http://fabien.seisen.org/python/ | |||
# | |||
# Also modified by Adam Ambrose (aambrose @T pacbell.net) to write data in | |||
# chunks (hardcoded to CHUNK_SIZE for now), so the entire contents of the file | |||
# don't need to be kept in memory. | |||
# | |||
""" | |||
enable to upload files using multipart/form-data | |||
idea from: | |||
upload files in python: | |||
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 | |||
timeoutsocket.py: overriding Python socket API: | |||
http://www.timo-tasi.org/python/timeoutsocket.py | |||
http://mail.python.org/pipermail/python-announce-list/2001-December/001095.html | |||
import urllib2_files | |||
import urllib2 | |||
u = urllib2.urlopen('http://site.com/path' [, data]) | |||
data can be a mapping object or a sequence of two-elements tuples | |||
(like in original urllib2.urlopen()) | |||
varname still need to be a string and | |||
value can be string of a file object | |||
eg: | |||
((varname, value), | |||
(varname2, value), | |||
) | |||
or | |||
{ name: value, | |||
name2: value2 | |||
} | |||
""" | |||
import os | |||
import socket | |||
import sys | |||
import stat | |||
import mimetypes | |||
import mimetools | |||
import httplib | |||
import urllib | |||
import urllib2 | |||
CHUNK_SIZE = 65536 | |||
def get_content_type(filename): | |||
return mimetypes.guess_type(filename)[0] or 'application/octet-stream' | |||
# if sock is None, juste return the estimate size | |||
def send_data(v_vars, v_files, boundary, sock=None): | |||
l = 0 | |||
for (k, v) in v_vars: | |||
buffer='' | |||
buffer += '--%s\r\n' % boundary | |||
buffer += 'Content-Disposition: form-data; name="%s"\r\n' % k | |||
buffer += '\r\n' | |||
buffer += v + '\r\n' | |||
if sock: | |||
sock.send(buffer) | |||
l += len(buffer) | |||
for (k, v) in v_files: | |||
fd = v | |||
file_size = os.fstat(fd.fileno())[stat.ST_SIZE] | |||
name = fd.name.split('/')[-1] | |||
if isinstance(name, unicode): | |||
name = name.encode('UTF-8') | |||
buffer='' | |||
buffer += '--%s\r\n' % boundary | |||
buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' \ | |||
% (k, name) | |||
buffer += 'Content-Type: %s\r\n' % get_content_type(name) | |||
buffer += 'Content-Length: %s\r\n' % file_size | |||
buffer += '\r\n' | |||
l += len(buffer) | |||
if sock: | |||
sock.send(buffer) | |||
if hasattr(fd, 'seek'): | |||
fd.seek(0) | |||
while True: | |||
chunk = fd.read(CHUNK_SIZE) | |||
if not chunk: break | |||
sock.send(chunk) | |||
l += file_size | |||
buffer='\r\n' | |||
buffer += '--%s--\r\n' % boundary | |||
buffer += '\r\n' | |||
if sock: | |||
sock.send(buffer) | |||
l += len(buffer) | |||
return l | |||
# mainly a copy of HTTPHandler from urllib2 | |||
class newHTTPHandler(urllib2.BaseHandler): | |||
def http_open(self, req): | |||
return self.do_open(httplib.HTTP, req) | |||
def do_open(self, http_class, req): | |||
data = req.get_data() | |||
v_files=[] | |||
v_vars=[] | |||
# mapping object (dict) | |||
if req.has_data() and type(data) != str: | |||
if hasattr(data, 'items'): | |||
data = data.items() | |||
else: | |||
try: | |||
if len(data) and not isinstance(data[0], tuple): | |||
raise TypeError | |||
except TypeError: | |||
ty, va, tb = sys.exc_info() | |||
raise TypeError, "not a valid non-string sequence or mapping object", tb | |||
for (k, v) in data: | |||
if hasattr(v, 'read'): | |||
v_files.append((k, v)) | |||
else: | |||
v_vars.append( (k, v) ) | |||
# no file ? convert to string | |||
if len(v_vars) > 0 and len(v_files) == 0: | |||
data = urllib.urlencode(v_vars) | |||
v_files=[] | |||
v_vars=[] | |||
host = req.get_host() | |||
if not host: | |||
raise urllib2.URLError('no host given') | |||
h = http_class(host) # will parse host:port | |||
if req.has_data(): | |||
h.putrequest('POST', req.get_selector()) | |||
if not 'Content-type' in req.headers: | |||
if len(v_files) > 0: | |||
boundary = mimetools.choose_boundary() | |||
l = send_data(v_vars, v_files, boundary) | |||
h.putheader('Content-Type', | |||
'multipart/form-data; boundary=%s' % boundary) | |||
h.putheader('Content-length', str(l)) | |||
else: | |||
h.putheader('Content-type', | |||
'application/x-www-form-urlencoded') | |||
if not 'Content-length' in req.headers: | |||
h.putheader('Content-length', '%d' % len(data)) | |||
else: | |||
h.putrequest('GET', req.get_selector()) | |||
scheme, sel = urllib.splittype(req.get_selector()) | |||
sel_host, sel_path = urllib.splithost(sel) | |||
h.putheader('Host', sel_host or host) | |||
for name, value in self.parent.addheaders: | |||
name = name.capitalize() | |||
if name not in req.headers: | |||
h.putheader(name, value) | |||
for k, v in req.headers.items(): | |||
h.putheader(k, v) | |||
# httplib will attempt to connect() here. be prepared | |||
# to convert a socket error to a URLError. | |||
try: | |||
h.endheaders() | |||
except socket.error, err: | |||
raise urllib2.URLError(err) | |||
if req.has_data(): | |||
if len(v_files) >0: | |||
l = send_data(v_vars, v_files, boundary, h) | |||
elif len(v_vars) > 0: | |||
# if data is passed as dict ... | |||
data = urllib.urlencode(v_vars) | |||
h.send(data) | |||
else: | |||
# "normal" urllib2.urlopen() | |||
h.send(data) | |||
code, msg, hdrs = h.getreply() | |||
fp = h.getfile() | |||
if code == 200: | |||
resp = urllib.addinfourl(fp, hdrs, req.get_full_url()) | |||
resp.code = code | |||
resp.msg = msg | |||
return resp | |||
else: | |||
return self.parent.error('http', req, fp, code, msg, hdrs) | |||
urllib2._old_HTTPHandler = urllib2.HTTPHandler | |||
urllib2.HTTPHandler = newHTTPHandler | |||
class newHTTPSHandler(newHTTPHandler): | |||
def https_open(self, req): | |||
return self.do_open(httplib.HTTPS, req) | |||
urllib2.HTTPSHandler = newHTTPSHandler | |||
#################################################################### | |||
# | |||
# Here comes the gopherchan client code. | |||
# | |||
# | |||
if __name__ == '__main__': | |||
import getopt | |||
import urllib2 | |||
import string | |||
import sys | |||
import os | |||
import tempfile | |||
# print short usage instructions | |||
def usage(progname): | |||
print """ | |||
Usage: %s [-n nickname] [-d delpass] [-m message] [-f file] [-k killpostno] (-b board | -t threadname) | |||
""" % progname | |||
board = False | |||
message = False | |||
file = False | |||
thread = False | |||
kill = False | |||
# read command line args | |||
try: | |||
opts, args = getopt.getopt(sys.argv[1:], 'hn:d:m:f:b:k:t:M:') | |||
except getopt.GetoptError, errmsg: | |||
print "ERROR:", errmsg | |||
sys.exit(1) | |||
for name, value in opts: | |||
if name == '-h': | |||
usage(sys.argv[0]) | |||
sys.exit(0) | |||
elif name == '-n': | |||
nickname = value | |||
elif name == '-d': | |||
delpass = value | |||
elif name == '-m': | |||
message = value | |||
elif name == '-f': | |||
file = value | |||
elif name == '-b': | |||
board = value | |||
elif name == '-k': | |||
kill = value | |||
elif name == '-t': | |||
thread = value | |||
elif name == '-M': | |||
try: | |||
fn = open(value, 'r') | |||
message = fn.read() | |||
fn.close() | |||
except IOError: | |||
print "Failed to read message from file" | |||
sys.exit(1) | |||
else: | |||
print "invalid argument:", name | |||
sys.exit(2) | |||
if(args != []): | |||
print "Superfluous arguments" | |||
sys.exit(2) | |||
if(kill != False): | |||
if(board == False): | |||
print "To kill a post, you must specify the board as well" | |||
sys.exit(1) | |||
if(thread == False and board == False): | |||
print "Either the thread or the board has to be specified." | |||
usage(sys.argv[0]) | |||
sys.exit(1) | |||
if(thread != False and board != False): | |||
print "The thread and the board can't be both specified at the same time" | |||
sys.exit(1) | |||
# open image file | |||
fileobj = False | |||
if(file != False): | |||
try: | |||
fileobj = open(file, 'rb') | |||
except IOError: | |||
print "Failed to open image file." | |||
# launch external editor to edit message | |||
if(message == False and kill == False): | |||
tf = tempfile.mkstemp('.txt', 'chan-'); | |||
if(os.system(editor + " '" + tf[1] + "'") != 0): | |||
print "Calling the editor failed:", editor + " '" + tf[1] + "'" | |||
sys.exit(1) | |||
mf = open(tf[1], 'r') | |||
message = mf.read().strip() | |||
mf.close() | |||
if(message == ''): | |||
print "Empty message, aborted" | |||
sys.exit(1) | |||
os.unlink(tf[1]) | |||
try: | |||
opts = { | |||
'author': nickname, | |||
'pass': delpass, | |||
'text': message, | |||
'board': '', | |||
'thread': '' | |||
} | |||
if(fileobj != False): | |||
opts['image'] = fileobj | |||
if(board != False): | |||
opts['board'] = board | |||
if(thread != False): | |||
opts['thread'] = thread | |||
if(kill != False): | |||
opts['kill'] = kill | |||
u = urllib2.urlopen(handler, opts) | |||
except urllib2.HTTPError, errobj: | |||
print "HTTP error:", errobj.code | |||
else: | |||
print u.read() | |||
</pre> | |||
}}|border=blue|background=white|margin=auto}} | |||
To post a comment: | |||
Customize this part of the .py file: | |||
nickname = 'anon' | |||
delpass = 'lofasz' | |||
handler = 'http://port70.net/cgi/post.cgi' | |||
editor = 'vim "+set tw=70" -c startinsert' | |||
And then use it like this: | |||
./chan.py [-n nickname] [-d delpass] [-m message] [-f file] [-k killpostno] (-b board | -t threadname) | |||
If you want to use a .txt file as message, use -M instead of -m. | |||
== External links == | |||
*[https://addons.mozilla.org/en-US/firefox/addon/overbiteff/ Overbite for Firefox] | |||
*[https://addons.mozilla.org/en-US/seamonkey/addon/overbiteff/ Overbite for SeaMonkey] | |||
*[http://gopher.floodgap.com/overbite/d?android Overbite for Android] | |||
{{Oldweb}} | |||
{{Softwarez}} | |||
{{Chans}} |
Latest revision as of 16:32, 25 August 2024
Gopher protocol is another protocol as it can be http or ftp. Its from the 90s, so only oldfags could know about it. Its more web 1.0 than Usenet or IRC. At the present is nearly dead, but there are some people still using it.
What is it?
The Gopher protocol is a TCP/IP application layer protocol designed for distributing, searching, and retrieving documents over the Internet. The Gopher protocol was strongly oriented towards a menu-document design and presented an alternative to the World Wide Web in its early stages, but ultimately HTTP became the dominant protocol. The Gopher ecosystem is often regarded as the effective predecessor of the World Wide Web.
The protocol was invented by a team led by Mark P. McCahill at the University of Minnesota. It offers some features not natively supported by the Web and imposes a much stronger hierarchy on information stored on it. Its text menu interface is well-suited to computing environments that rely heavily on remote text-oriented computer terminals, which were still common at the time of its creation in 1991, and the simplicity of its protocol facilitated a wide variety of client implementations. More recent Gopher revisions and graphical clients added support for multimedia. Gopher was preferred by many network administrators for using fewer network resources than Web services.
Gopher's hierarchical structure provided a platform for the first large-scale electronic library connections. Gopher has been described by some enthusiasts as "faster and more efficient and so much more organised" than today's Web services. The Gopher protocol is still in use by enthusiasts, and a small population of actively maintained servers remain although it has been almost entirely supplanted by the Web.
What can you find on Gopher?
- ASCII pr0n
- ASCII pr0n
- Ancient web sites
- Archives of all kind
- Faggots
- ASCII pr0n
- Gopherchan
How to access Gopher sites?
You need a browser compatible with gopher protocol, of the main browsers the only one that supports it is Mozilla Firefox and its forks by installing an addon called OverbiteFF. Once you install it you can access a bigger ammount of the net, since search engines dont index gopher sites, so its the best place to hide something online apart from local servers or in Onionland.
How to browse them?
Do I need to explain this???? If you cant navigate properly on gopher sites GTFO of the internet.
Gopher sites
- Veronica2 Gopher search engine
- Gopherchan
- Some of the most modern gopher sites
- xkcd
- ASCII text maker
- A huge ASCII art library
NOTE: there are more
Gopherchan
Gopherchan is probably the most web 1.0 chan out there, its also one of the smallests, it only has 2 boards: /b/ and /paste/ and to be able to post on it you need to use the following python file as explained:
#!/usr/bin/env python # client configuration nickname = 'anon' delpass = 'lofasz' handler = 'http://port70.net/cgi/post.cgi' editor = 'vim "+set tw=70" -c startinsert' # # below, the urllib2_file library is embedded # got it from: http://fabien.seisen.org/python/urllib2_multipart.html # ############################# # # Version: 0.2.0 # - UTF-8 filenames are now allowed (Eli Golovinsky)<br/> # - File object is no more mandatory, Object only needs to have seek() read() attributes (Eli Golovinsky)<br/> # # Version: 0.1.0 # - upload is now done with chunks (Adam Ambrose) # # Version: older # THANKS TO: # bug fix: kosh @T aesaeion.com # HTTPS support : Ryan Grow <ryangrow @T yahoo.com> # Copyright (C) 2004,2005,2006 Fabien SEISEN # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # you can contact me at: <[email protected]> # http://fabien.seisen.org/python/ # # Also modified by Adam Ambrose (aambrose @T pacbell.net) to write data in # chunks (hardcoded to CHUNK_SIZE for now), so the entire contents of the file # don't need to be kept in memory. # """ enable to upload files using multipart/form-data idea from: upload files in python: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 timeoutsocket.py: overriding Python socket API: http://www.timo-tasi.org/python/timeoutsocket.py http://mail.python.org/pipermail/python-announce-list/2001-December/001095.html import urllib2_files import urllib2 u = urllib2.urlopen('http://site.com/path' [, data]) data can be a mapping object or a sequence of two-elements tuples (like in original urllib2.urlopen()) varname still need to be a string and value can be string of a file object eg: ((varname, value), (varname2, value), ) or { name: value, name2: value2 } """ import os import socket import sys import stat import mimetypes import mimetools import httplib import urllib import urllib2 CHUNK_SIZE = 65536 def get_content_type(filename): return mimetypes.guess_type(filename)[0] or 'application/octet-stream' # if sock is None, juste return the estimate size def send_data(v_vars, v_files, boundary, sock=None): l = 0 for (k, v) in v_vars: buffer='' buffer += '--%s\r\n' % boundary buffer += 'Content-Disposition: form-data; name="%s"\r\n' % k buffer += '\r\n' buffer += v + '\r\n' if sock: sock.send(buffer) l += len(buffer) for (k, v) in v_files: fd = v file_size = os.fstat(fd.fileno())[stat.ST_SIZE] name = fd.name.split('/')[-1] if isinstance(name, unicode): name = name.encode('UTF-8') buffer='' buffer += '--%s\r\n' % boundary buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' \ % (k, name) buffer += 'Content-Type: %s\r\n' % get_content_type(name) buffer += 'Content-Length: %s\r\n' % file_size buffer += '\r\n' l += len(buffer) if sock: sock.send(buffer) if hasattr(fd, 'seek'): fd.seek(0) while True: chunk = fd.read(CHUNK_SIZE) if not chunk: break sock.send(chunk) l += file_size buffer='\r\n' buffer += '--%s--\r\n' % boundary buffer += '\r\n' if sock: sock.send(buffer) l += len(buffer) return l # mainly a copy of HTTPHandler from urllib2 class newHTTPHandler(urllib2.BaseHandler): def http_open(self, req): return self.do_open(httplib.HTTP, req) def do_open(self, http_class, req): data = req.get_data() v_files=[] v_vars=[] # mapping object (dict) if req.has_data() and type(data) != str: if hasattr(data, 'items'): data = data.items() else: try: if len(data) and not isinstance(data[0], tuple): raise TypeError except TypeError: ty, va, tb = sys.exc_info() raise TypeError, "not a valid non-string sequence or mapping object", tb for (k, v) in data: if hasattr(v, 'read'): v_files.append((k, v)) else: v_vars.append( (k, v) ) # no file ? convert to string if len(v_vars) > 0 and len(v_files) == 0: data = urllib.urlencode(v_vars) v_files=[] v_vars=[] host = req.get_host() if not host: raise urllib2.URLError('no host given') h = http_class(host) # will parse host:port if req.has_data(): h.putrequest('POST', req.get_selector()) if not 'Content-type' in req.headers: if len(v_files) > 0: boundary = mimetools.choose_boundary() l = send_data(v_vars, v_files, boundary) h.putheader('Content-Type', 'multipart/form-data; boundary=%s' % boundary) h.putheader('Content-length', str(l)) else: h.putheader('Content-type', 'application/x-www-form-urlencoded') if not 'Content-length' in req.headers: h.putheader('Content-length', '%d' % len(data)) else: h.putrequest('GET', req.get_selector()) scheme, sel = urllib.splittype(req.get_selector()) sel_host, sel_path = urllib.splithost(sel) h.putheader('Host', sel_host or host) for name, value in self.parent.addheaders: name = name.capitalize() if name not in req.headers: h.putheader(name, value) for k, v in req.headers.items(): h.putheader(k, v) # httplib will attempt to connect() here. be prepared # to convert a socket error to a URLError. try: h.endheaders() except socket.error, err: raise urllib2.URLError(err) if req.has_data(): if len(v_files) >0: l = send_data(v_vars, v_files, boundary, h) elif len(v_vars) > 0: # if data is passed as dict ... data = urllib.urlencode(v_vars) h.send(data) else: # "normal" urllib2.urlopen() h.send(data) code, msg, hdrs = h.getreply() fp = h.getfile() if code == 200: resp = urllib.addinfourl(fp, hdrs, req.get_full_url()) resp.code = code resp.msg = msg return resp else: return self.parent.error('http', req, fp, code, msg, hdrs) urllib2._old_HTTPHandler = urllib2.HTTPHandler urllib2.HTTPHandler = newHTTPHandler class newHTTPSHandler(newHTTPHandler): def https_open(self, req): return self.do_open(httplib.HTTPS, req) urllib2.HTTPSHandler = newHTTPSHandler #################################################################### # # Here comes the gopherchan client code. # # if __name__ == '__main__': import getopt import urllib2 import string import sys import os import tempfile # print short usage instructions def usage(progname): print """ Usage: %s [-n nickname] [-d delpass] [-m message] [-f file] [-k killpostno] (-b board | -t threadname) """ % progname board = False message = False file = False thread = False kill = False # read command line args try: opts, args = getopt.getopt(sys.argv[1:], 'hn:d:m:f:b:k:t:M:') except getopt.GetoptError, errmsg: print "ERROR:", errmsg sys.exit(1) for name, value in opts: if name == '-h': usage(sys.argv[0]) sys.exit(0) elif name == '-n': nickname = value elif name == '-d': delpass = value elif name == '-m': message = value elif name == '-f': file = value elif name == '-b': board = value elif name == '-k': kill = value elif name == '-t': thread = value elif name == '-M': try: fn = open(value, 'r') message = fn.read() fn.close() except IOError: print "Failed to read message from file" sys.exit(1) else: print "invalid argument:", name sys.exit(2) if(args != []): print "Superfluous arguments" sys.exit(2) if(kill != False): if(board == False): print "To kill a post, you must specify the board as well" sys.exit(1) if(thread == False and board == False): print "Either the thread or the board has to be specified." usage(sys.argv[0]) sys.exit(1) if(thread != False and board != False): print "The thread and the board can't be both specified at the same time" sys.exit(1) # open image file fileobj = False if(file != False): try: fileobj = open(file, 'rb') except IOError: print "Failed to open image file." # launch external editor to edit message if(message == False and kill == False): tf = tempfile.mkstemp('.txt', 'chan-'); if(os.system(editor + " '" + tf[1] + "'") != 0): print "Calling the editor failed:", editor + " '" + tf[1] + "'" sys.exit(1) mf = open(tf[1], 'r') message = mf.read().strip() mf.close() if(message == ''): print "Empty message, aborted" sys.exit(1) os.unlink(tf[1]) try: opts = { 'author': nickname, 'pass': delpass, 'text': message, 'board': '', 'thread': '' } if(fileobj != False): opts['image'] = fileobj if(board != False): opts['board'] = board if(thread != False): opts['thread'] = thread if(kill != False): opts['kill'] = kill u = urllib2.urlopen(handler, opts) except urllib2.HTTPError, errobj: print "HTTP error:", errobj.code else: print u.read() |
To post a comment:
Customize this part of the .py file:
nickname = 'anon' delpass = 'lofasz' handler = 'http://port70.net/cgi/post.cgi' editor = 'vim "+set tw=70" -c startinsert'
And then use it like this:
./chan.py [-n nickname] [-d delpass] [-m message] [-f file] [-k killpostno] (-b board | -t threadname)
If you want to use a .txt file as message, use -M instead of -m.
External links
Gopher protocol is part of a series on Web 1.0 |
[ANCIENT HISTORY] Old Memes •
Celebs, h4x0rz, and Phreaks •
Technologies •
Fun and Games •
Events •
Death of Web1.0
|
---|
Gopher protocol is part of a series on Visit the Softwarez Portal for complete coverage. |
Gopher protocol is part of a series on Visit the Chans Portal for complete coverage. |