Send . txt file from one pc to another using http service

Asked

Viewed 1,203 times

4

I need to send a file from one PC to another over the network, only using requests http, so I don’t have to lower the level of socket, that takes work. Someone enables me to clear up with some API or code example?

PS: I’m not lazy, I even found a few things, only I had to make a mini server and I’m kind of layabout it.
Ah, I’m using Java and/or Python.

  • This post: Sockets in java or that: Creation and communication with daemon, maybe help.

  • 2

    Maybe you can install a "ready" server on one side (e.g., Apache), and use the: urllib2 to request. It seems to be easier.

  • 1

    Apache is not a "ready server" for receiving text files - you need a server-side application that is invoked by Apache to handle the http request that sends a file.

  • python also has requests on its own project site have some examples http://pt.python-requests.org/en/latest/

  • Guys, I have already solved this problem using a python mini server and more details. You find it interesting that I post the solution here as an answer?

1 answer

3


Receiving an HTTP file as a web request without using a framework is not so trivial:

To ensure the passage of the file data, along with other possible form data, and other things that go in an HTTP post, the thing is very boring.

I made a program in Python 3- without using a framework, just using the http.server module to receive a file - it works, but starts "in the box" the file data from inside the HTTP post, without parsing correctly. Surely there are dozens of corner-cases that are not treated (it is not that they are not treated properly - they are simply not treated). In particular the post data is read as "bytes" and does not have available the cool Python methods of searching and cutting strings. In particular I do a necessary gambiarra: a transparent conversion of these "bytes" to string with the "latin1" codec - this preserves the numeric value of each byte, as a Unicode character of equivalent value in the string - and in the string object, I can use split, find, Slices, etc...

On the other hand, I think it’s a nice example of how to use Python 3’s "http.server" (Basehttpserver module) in Python2.

# coding: utf-8
from http.server import HTTPServer, BaseHTTPRequestHandler
import cgi

UPLOAD_DIR = "/tmp/"

class FileSaver(BaseHTTPRequestHandler):
    def _headers(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html;charset=utf-8")
        self.end_headers()

    def do_POST(self):
        files = []
        try: 
            raw_file_content = self.rfile.read(int( self.headers.get('content-length')))
            data = raw_file_content.decode("latin1")
            while True:
                try:
                    header, data = data.split("\r\n\r\n", 1)
                except ValueError:
                    break
                boundary_str = header.split("\r\n", 1)[0]
                if "filename" in header:
                    file_data = data.split("\r\n" + boundary_str)[0].encode("latin1")
                    filename = header.split('filename="')[1].split('"')[0]

                    with open(UPLOAD_DIR + filename, "wb") as file_:
                        file_.write(file_data)
                    files.append(filename)
                data = data[data.find(boundary_str):]
                if len(data) < 2:
                    break
        except Exception as exc:
            self.send_response(500)
            self.send_header("Content-type", "text/plain;charset=utf-8")
            self.end_headers()
            self.wfile.write(str(exc).encode("utf-8"))
            raise
        self._headers()
        self.wfile.write("""<h1 style="color:red">upload of {} ok</h1>""".format(filename).encode("utf-8"))
        return

    def do_GET(self):
        self._headers()

        self.wfile.write("""<h1 style="color:red">Alô mundo!!</h1>
            <form method="post" action="/" enctype="multipart/form-data">
            arquivo: <input type="file" name="arquivo"><br/>
            <input type="submit" value="ok" / >
            </form>

            """.encode("utf-8"))
        return


if __name__ == "__main__":
    server = HTTPServer(("0.0.0.0", 8000), FileSaver)
    server.serve_forever()

Of course using a framework like Flask, it’s well easier to do that. A view that saves a file that came to a forum in Flask using the WTF form extension (with the framework already taking care of all the cornercases above) would be something like:

from flask import Flask, render_template
import flask_wtf

app = Flask(__name__)

class FileForm(form):
     file = flask_wtf.file.FileField

@route("/upload", methods=["POST"])
def upload(form, id):
    form.file.data.save("/tmp/" + form.file.data.filename)
    return render_template(...)

(This code in Flask is not complete and has not been tested - the above raw Pythno works as is)

Already the code to post a file by HTTP - again, if using Python "raw" can be quite complicated - but in this case, we can use the method "requests" that accepts a parameter "file" directly (it receives a dictionary with the name of the file field and an open file, which we wish to send):

>>> requests.post("http://localhost:8000", files={"arquivo": open("imagem.png", "rb")  } )

Only this call uploads the file to the list 1 server above.

Now, it’s one thing to want to play with it, it’s another to want to use it in production - in this case it’s better to either use the framework, of course, or use xmlrpc (or jsonrpc) - it’s going to be an easier order of magnitude.

  • Speak friend, I myself futicando ended up achieving, and you know what? Precisely using the Flask!!! I made the Sender in java, and the mini server in python with flask, but thanks guy!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.